-
Notifications
You must be signed in to change notification settings - Fork 319
/
_P104_SRF02.ino
152 lines (126 loc) · 4.76 KB
/
_P104_SRF02.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//#######################################################################################################
//######################### Plugin 104: SRF02 Ultrasonic range finder sensor ############################
//#######################################################################################################
#define PLUGIN_104
#define PLUGIN_ID_104 104
#define PLUGIN_NAME_104 "Ultrasonic range finder - SRF02"
#define PLUGIN_VALUENAME1_104 "DISTANCE"
#define SRF02_ADDRESS (0x70) // default address (0x70 = datasheet address 0xE0)
#define SRF02_REG_COMMAND (0x00) // a read on this register returns the software revision
#define SRF02_REG_UNUSED (0x01)
#define SRF02_REG_RANGE_HIGH_BYTE (0x02)
#define SRF02_REG_RANGE_LOW_BYTE (0x03)
#define SRF02_REG_AUTOTUNE_MINIMUM_HIGH_BYTE (0x04)
#define SRF02_REG_AUTOTUNE_MINIMUM_LOW_BYTE (0x05)
#define SRF02_CMD_REAL_RANGING_MODE_INCH (0x50)
#define SRF02_CMD_REAL_RANGING_MODE_CM (0x51)
#define SRF02_CMD_REAL_RANGING_MODE_US (0x52)
#define SRF02_CMD_FAKE_RANGING_MODE_INCH (0x56)
#define SRF02_CMD_FAKE_RANGING_MODE_CM (0x57)
#define SRF02_CMD_FAKE_RANGING_MODE_US (0x58)
#define SRF02_CMD_FORCE_AUTOTUNE_RESTART (0x5C)
#define SRF02_CMD_I2C_CHANGE_SEQ_1 (0xA0)
#define SRF02_CMD_I2C_CHANGE_SEQ_2 (0xA5)
#define SRF02_CMD_I2C_CHANGE_SEQ_3 (0xAA)
uint8_t SRF02_i2caddr;
boolean Plugin_104(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_104;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = SENSOR_TYPE_SINGLE;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].TimerOptional = true;
Device[deviceCount].ValueCount = 1;
Device[deviceCount].SendDataOption = true;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_104);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_104));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
success = true;
break;
}
case PLUGIN_INIT:
{
Plugin_104_begin();
success = true;
break;
}
case PLUGIN_READ:
{
float value;
value = Plugin_104_getDistance();
UserVar[event->BaseVarIndex] = value;
String log = F("P104 : distance = ");
log += value;
log += F(" mm");
addLog(LOG_LEVEL_INFO,log);
success = true;
break;
}
}
return success;
}
//**************************************************************************/
// I2C single byte write
//**************************************************************************/
void Plugin_104_wireWriteByte(uint8_t reg, uint8_t value)
{
Wire.beginTransmission(SRF02_i2caddr);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
//**************************************************************************/
// I2C two byte read
//**************************************************************************/
void Plugin_104_wireReadTwoBytes(uint8_t reg, uint16_t *value)
{
Wire.beginTransmission(SRF02_i2caddr);
Wire.write(reg);
Wire.endTransmission();
delayMicroseconds(10);
Wire.requestFrom(SRF02_i2caddr, (uint8_t)2);
*value = ((Wire.read() << 8) | Wire.read());
}
//**************************************************************************/
// Sensor setup
//**************************************************************************/
void Plugin_104_begin(void)
{
SRF02_i2caddr = SRF02_ADDRESS;
}
//**************************************************************************/
// Report distance
//**************************************************************************/
float Plugin_104_getDistance()
{
uint16_t value;
Plugin_104_wireWriteByte(SRF02_REG_COMMAND, SRF02_CMD_REAL_RANGING_MODE_US);
delay(70); // transmit -> receive turnaround time (up to 65ms)
Plugin_104_wireReadTwoBytes(SRF02_REG_RANGE_HIGH_BYTE, &value);
return (float)value/(float)5.82750583; // distance in [mm] (2*1000/343.2)
}