MatrixMiniR4 1.1.5
Matrix Mini R4 Arduino Library API Documentation
Loading...
Searching...
No Matches
MiniR4VernierLib.cpp
Go to the documentation of this file.
1
6/* This is a library to make using Vernier LabQuest sensors and the Digital Control Unit (DCU)
7with a Vernier Arduino Interface Shield (BT-ARD) easier. There are several useful functions:
8AutoID: reads information about the sensor, including calibration information
9readSensor: returns calibrated sensor data from Analog 1
10readMotionDetector: returns the distance reading from a Vernier Motion Detector in Digital 1
11DCU: allows you to control the output of a Vernier Digital Control Unit (DCU) in Digital 2
12DCUStep: allows you to easily control a stepper motor connected to the DCU in Digital 2
13DCUPWM: allows you to use PWM from the DCU line 4 in Digital 2
14
15Version 1.0.6 fixes an error that occurred from how _sensorName, _shorName, and _sensorUnits were
16initialized with a const char value.
17*/
18
19// #define DEBUG1 // add for print statements
20// single channel version
21#include "MiniR4VernierLib.h"
22#include "Arduino.h"
23#include <Wire.h> // used for I2C communication
24
26{
27 pinMode(2, INPUT); // Echo pin; this is the pin that goes high when an echo is received
28 pinMode(3, OUTPUT); // Trigger Pin used for Motion Detector
29 pinMode(6, OUTPUT); // set up DCU lines, assuming it is on Digital 2
30 pinMode(7, OUTPUT);
31 pinMode(8, OUTPUT);
32 pinMode(9, OUTPUT);
33 pinMode(10, OUTPUT); // multiplexer on the shield, lsb
34 pinMode(11, OUTPUT); // multiplexer on the shield, msb
35 pinMode(12, INPUT_PULLUP); // button on DCU
36 pinMode(13, OUTPUT); // LED on shield
37}
38
40{
41 _channel = 1; //this is the Analog 1 only version of the library\
43 _voltageID = 0;
44 _slope = 1;
45 _intercept = 0;
46 _cFactor = 0;
47 _page = 0; // calibration storage page (always 0 for resistor ID sensors)
48 _calEquationType = 1; // for all resisto-ID sensrs, but thermistors and some I2C sensors; it
49 // will be changed in that case below
50 const int _device = 0x50; // used for I2C autoID
51 byte _floatbyte[5];
52 byte _sensorData[128];
53 for (_i = 0; _i < 128; _i++) // clear our digital ID sensor data
54 {
55 _sensorData[_i] = 0;
56 }
57
58 byte _resistorIDInfo[][32] = {
59 {78, 97, 109, 101, 32, 48, 32, 32, 32, 32, 32, 32, 32, 32, 83, 104,
60 111, 114, 116, 78, 97, 109, 101, 32, 85, 110, 105, 116, 115, 32, 32, 0},
61 {84, 72, 101, 114, 109, 111, 99, 111, 117, 112, 108, 101, 32, 32, 84, 101, 109,
62 112, 32, 32, 32, 32, 32, 32, 68, 101, 103, 32, 67, 32, 32, 0}, // Thermocouple*
63 {86, 111, 108, 116, 97, 103, 101, 32, 43, 47, 45, 49, 48, 86, 86, 32,
64 32, 32, 32, 32, 32, 32, 32, 32, 86, 32, 32, 32, 32, 32, 32, 0}, // voltage +/-10*
65 {67, 117, 114, 114, 101, 110, 116, 32, 32, 32, 32, 32, 32, 32, 73, 32,
66 32, 32, 32, 32, 32, 32, 32, 32, 65, 32, 32, 32, 32, 32, 32, 0}, // Current*
67 {82, 101, 115, 105, 115, 116, 97, 110, 99, 101, 32, 32, 32, 32, 82, 101,
68 115, 32, 32, 32, 32, 32, 32, 32, 79, 104, 109, 115, 32, 32, 32, 0}, // resistance*
69 {69, 76, 32, 84, 101, 109, 112, 32, 32, 32, 32, 32, 32, 32, 84, 101,
70 109, 112, 32, 32, 32, 32, 32, 32, 68, 101, 103, 32, 67, 32, 32, 0}, // 5 EL Temp*
71 {109, 105, 115, 115, 105, 110, 103, 32, 32, 32, 32, 32, 32, 32, 109, 105,
72 115, 115, 105, 110, 103, 32, 32, 32, 109, 105, 115, 115, 105, 110, 103, 0}, // missing*
73 {109, 105, 115, 115, 105, 110, 103, 32, 32, 32, 32, 32, 32, 32, 109, 105,
74 115, 115, 105, 110, 103, 32, 32, 32, 109, 105, 115, 115, 105, 110, 103, 0}, // missing*
75 {68, 105, 102, 102, 32, 86, 111, 108, 116, 97, 103, 101, 32, 32, 80, 111,
76 116, 32, 32, 32, 32, 32, 32, 32, 86, 32, 32, 32, 32, 32, 32, 0}, // Diff voltage*
77 {67, 117, 114, 114, 101, 110, 116, 32, 32, 32, 32, 32, 32, 32, 73, 32,
78 32, 32, 32, 32, 32, 32, 32, 32, 65, 32, 32, 32, 32, 32, 32, 0}, // Current*
79 {84, 101, 109, 112, 101, 114, 97, 116, 117, 114, 101, 32, 32, 32, 84, 101,
80 109, 112, 32, 32, 32, 32, 32, 32, 68, 101, 103, 32, 67, 32, 32, 0}, // 10 Temp*
81 {86, 111, 108, 116, 97, 103, 101, 32, 43, 47, 45, 51, 48, 86, 80, 111,
82 116, 32, 32, 32, 32, 32, 32, 32, 86, 32, 32, 32, 32, 32, 32, 0}, // voltage +/-30*
83 {84, 73, 32, 76, 105, 103, 104, 116, 32, 32, 32, 32, 32, 32, 76, 105,
84 103, 104, 116, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0}, // TI Light*
85 {69, 120, 32, 72, 101, 97, 114, 116, 32, 82, 97, 116, 101, 32, 86, 32,
86 32, 32, 32, 32, 32, 32, 32, 32, 86, 32, 32, 32, 32, 32, 32, 0}, // Ex Heart Rate*
87 {82, 97, 119, 32, 86, 111, 108, 116, 115, 32, 32, 32, 32, 32, 86, 32,
88 32, 32, 32, 32, 32, 32, 32, 32, 86, 32, 32, 32, 32, 32, 32, 0}, // Raw Volts*
89 {69, 75, 71, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 69, 75,
90 71, 32, 32, 32, 32, 32, 2, 86, 32, 32, 32, 32, 32, 32, 0}, // 15 EKG*
91 {109, 105, 115, 115, 105, 110, 103, 32, 32, 32, 32, 32, 32, 32, 109, 105,
92 115, 115, 105, 110, 103, 32, 32, 32, 109, 105, 115, 115, 105, 110, 103, 0}, // missing*
93 {67, 97, 114, 98, 111, 110, 32, 68, 105, 111, 120, 105, 100, 101, 67, 79,
94 50, 32, 32, 32, 32, 32, 32, 32, 112, 112, 109, 32, 32, 32, 32, 0}, // CO2*
95 {79, 120, 121, 103, 101, 110, 32, 32, 32, 32, 32, 32, 32, 32, 79, 50,
96 32, 32, 32, 32, 32, 32, 32, 32, 37, 32, 32, 32, 32, 32, 32, 0} // O2*};
97 };
98
99 _sensorName[16] = '\0'; // I am using 16 characters here, plus terminator.
100 _shortName[12] = '\0'; // 12 characters on name, plus terminator.
101 _sensorUnits[7] = '\0'; // 7 characters units, plus terminator.
102 _sensorName[17] = '\0'; // THESE MAY NOT BE NECESSARY
103 _shortName[13] = '\0';
104 _sensorUnits[8] = '\0';
105 // set multiplexer to match channel: NOTE THIS IS GETTING READY FOR A 2-CHANNEL VERSION
106 if (_channel == 1) {
107 digitalWrite(10, LOW); // set multiplexer for BTA1
108 } else {
109 digitalWrite(10, HIGH); // set multiplexer for BTA2
110 }
111 digitalWrite(11, LOW); //
112
113#if defined DEBUG1
114 Serial.print("_resistorIDInfo array: "); // only if "#define" is in the code
115 for (_i = 0; _i < 33; _i++) // display whole line of array as numbers
116 {
117 Serial.print(_resistorIDInfo[_sensorNumber][_i]);
118 Serial.print(",");
119 }
120 Serial.println("}");
121 Serial.println("_resistorIDInfo array as char: "); // only if "#define" is in the code
122 for (_i = 0; _i < 33; _i++) // display whole line of array as characters
123 {
124 Serial.print(char(_resistorIDInfo[_sensorNumber][_i]));
125 }
126 Serial.println("}");
127#endif // DEBUG1
128
129 // Read BTA1 Sensor with resistor ID:
130 _voltageID = analogRead(A5) / 1024.0 * 5.00; // convert from count to voltage could use Vcc!!!
131 if (_voltageID > 0.86 & _voltageID < 0.95) _sensorNumber = 1; // Thermocouple
132 if (_voltageID > 3.72 & _voltageID < 3.86) _sensorNumber = 2; // voltage +/-10 V
133 if (_voltageID > 1.92 & _voltageID < 2.13) _sensorNumber = 3; // TI Current Probe (not used)
134 if (_voltageID > 1.18 & _voltageID < 1.30) _sensorNumber = 4; // resistance
135 if (_voltageID > 3.27 & _voltageID < 3.68) _sensorNumber = 5; // Extra-Long Temperature Probe
136 if (_voltageID > 4.64 & _voltageID < 4.73) _sensorNumber = 8; // Differential voltage
137 if (_voltageID > 4.73 & _voltageID < 4.82) _sensorNumber = 9; // Current
138 if (_voltageID > 2.38 & _voltageID < 2.63)
139 _sensorNumber = 10; // Stainless Steel or Surface Temperature Probe
140 if (_voltageID > 2.85 & _voltageID < 3.15) _sensorNumber = 11; // voltage 30 V
141 if (_voltageID > 1.52 & _voltageID < 1.68) _sensorNumber = 12; // TILT, TI Light Sensor
142 if (_voltageID > 0.43 & _voltageID < 0.48) _sensorNumber = 13; // Exercise Heart Rate
143 if (_voltageID > 4.08 & _voltageID < 4.16) _sensorNumber = 14; // Raw voltage
144 if (_voltageID > 0.62 & _voltageID < 0.68) _sensorNumber = 15; // EKG
145 if (_voltageID > 4.32 & _voltageID < 4.40) _sensorNumber = 17; // CO2
146 if (_voltageID > 4.50 & _voltageID < 4.59) _sensorNumber = 18; // Oxygen
147
148 if (_sensorNumber != 0) // if any resistor ID sensor found
149 {
150 // code below assumes the _resistorIDInfo array is correct and sticks those numbers, for a
151 // particular sensor into the sensorData array. read Name char string into array in the righ
152 for (_i = 0; _i < 14; _i++) //
153 {
154 _sensorData[9 + _i] = _resistorIDInfo[_sensorNumber][_i];
155 }
156 // read ShortName char string into array in the right spots, characters 15-24
157 for (_i = 0; _i < 10; _i++) //
158 {
159 _sensorData[29 + _i] = _resistorIDInfo[_sensorNumber][14 + _i];
160 }
161 // read Units char string into array in the right spots, characters 25-32
162 for (_i = 0; _i < 7; _i++) //
163 {
164 _sensorData[83 + _i] =
165 _resistorIDInfo[_sensorNumber][24 + _i]; // note page is always 0
166 }
167
168 switch (_sensorNumber) {
169 case 1:
170 // Thermocouple ;
171 _slope = -2.45455;
172 _intercept = 6.2115;
173 break;
174 case 2:
175 // voltage +/- 10V" ;
176 _slope = 4; // note correction for Sparkfun circuit done in calculation of voltage!
177 _intercept = -10;
178 break;
179 case 3:
180 // Current;
181 _slope = -2.665;
182 _intercept = 6.325;
183 break;
184 case 4:
185 // resistance ;
186 _slope = -2.5;
187 _intercept = 6.25;
188 break;
189 case 5:
190 // EL Temp //Extra-Long Temperature Probe
191 _slope = 58.341;
192 _intercept = -53.073;
193 break;
194 case 8:
195 // Diff voltage ;
196 _slope = -2.5;
197 _intercept = 6.25;
198 break;
199 case 9:
200 // Current ;
201 _slope = -0.25;
202 _intercept = 0.625;
203 break;
204 case 10:
205 // Temperature ;
206 _slope = 1;
207 _intercept = 0;
208 _calEquationType = 12; // Steinhart-Hart (for this sensor only)
209 break;
210 case 11:
211 // voltage +/- 30V" ;//
212 _slope = 15.41;
213 _intercept = -40.35;
214 break;
215 case 12:
216 // TI Light ;
217 _slope = 1;
218 _intercept = 0;
219 break;
220 case 13:
221 // Exercise Heart Rate ;
222 _slope = 1;
223 _intercept = 0;
224 break;
225 case 14:
226 // Raw voltage ;
227 _slope = 1;
228 _intercept = 0;
229 break;
230 case 15:
231 // EKG ;
232 _slope = 1;
233 _intercept = 0;
234 break;
235 case 17:
236 // Carbon Dioxide ;
237 _slope = 1;
238 _intercept = 0;
239 break;
240 case 18:
241 // Oxygen ;
242 _slope = 1;
243 _intercept = 0;
244 break;
245 default:
246 _slope = 1;
247 _intercept = 0;
248 break;
249 } // end of switch case
250 } // end of if a resistor ID sensor is found
251
252
253
254 if (_sensorNumber == 0) // no resistor ID sensor found; check I2C
255 {
256 pinMode(A4, OUTPUT); // Turn on the I2C communication!!! this can cause problems!!!
257 pinMode(A5, OUTPUT);
258
259 // check for digital ID sensor:
260 Wire.begin(); // join i2c bus (address optional for master)
261 // Reading _device first time... ;
262 Wire.beginTransmission(_device); // Now we're going to read it back
263 Wire.write(0x0); // Sending address 0, so it knows where we'll want
264 Wire.endTransmission();
265 int _x =
266 Wire.requestFrom(_device, 32); // Start new transmission and keep reading for 32 bytes
267 // note: the default buffer size for Arduino is 23 bytes. You can change it to larger. It
268 // would be desirable to change it to 128 bytes and read all the data in one read. That is
269 // the way all Vernier
270 // interfaces do it. is done as follows: add#define SERIAL_BUFFER_SIZE 128
271 // check it in your sketch with:
272 // Serial.print(SERIAL_BUFFER_SIZE);
273 _i = 1;
274 while (_x > 1) {
275 _x = Wire.available();
276 byte _c = Wire.read(); // Read a byte and write it out to the Serial port
277 _sensorData[_i] = _c;
278 _i++;
279 }
280 // Reading device second time... ;
281 Wire.beginTransmission(_device); // Now we're going to read it back
282 Wire.write(0x20); // Sending address 0, so it knows where we'll want
283 Wire.endTransmission(); // to read from
284 _x = Wire.requestFrom(
285 _device, 32); // Start new transmission and keep reading for 128 bytes
286 _i = 1;
287 while (_x > 1) {
288 _x = Wire.available();
289 byte _c = Wire.read(); // Read a byte and write it out to the Serial port
290 _sensorData[_i + 32] = _c;
291 _i++;
292 }
293 // Reading device third time... ;
294 Wire.beginTransmission(_device); // Now we're going to read it back
295 Wire.write(0x40); // Sending address 0, so it knows where we'll want
296 Wire.endTransmission(); // to read from
297 _x = Wire.requestFrom(
298 _device, 32); // Start new transmission and keep reading for 128 bytes
299 _i = 1;
300 while (_x > 1) {
301 _x = Wire.available();
302 byte _c = Wire.read(); // Read a byte and write it out to the Serial port
303 _sensorData[_i + 64] = _c;
304 _i++;
305 }
306 // Reading device a forth time... ;
307 Wire.beginTransmission(_device); // Now we're going to read it back
308 Wire.write(0x60); // Sending address 0, so it knows where we'll want
309 Wire.endTransmission(); // to read from
310 _x = Wire.requestFrom(
311 _device, 32); // Start new transmission and keep reading for 128 bytes
312 _i = 1;
313 while (_x > 1) {
314 _x = Wire.available();
315 byte _c = Wire.read(); // Read a byte and write it out to the Serial port
316 _sensorData[_i + 96] = _c;
317 _i++;
318 }
319 _voltageID = -1;
320 ; // Determines the sensorNumber:
321 _sensorNumber = _sensorData[2];
322
323 // Determine the calibration equation type:
324 _calEquationType = _sensorData[57];
325
326 // Determines the calibration page:
327 _page = _sensorData[70];
328 // the code below uses the calibration page set:
329 // Intercept starts at 71 for page 1, 90 for p2, and 109 for p3
330
331 // Determines intercept:
332 for (_i = 0; _i < 4; _i++) {
333 _floatbyte[_i] = _sensorData[_i + 71 + (_page) * 19];
334 }
335 float _j = *(float*)&_floatbyte;
336 _intercept = _j;
337
338 // Determines slope:
339 // slope starts at 75 for page 1, 94 for p2, and 113 for p3
340 for (_i = 0; _i < 4; _i++) {
341 _floatbyte[_i] = _sensorData[_i + 75 + (_page * 19)];
342 }
343 float _y = *(float*)&_floatbyte;
344 _slope = _y;
345
346 pinMode(A4, INPUT); // Turn off the I2C communication!!! this can cause problems!!!
347 pinMode(A5, INPUT);
348
349 } // end of if I2C autoID
350
351
352 // Determine the sensor name:
353 for (_i = 0; _i < 16; _i++) {
354 char _c = _sensorData[_i + 9];
355 _sensorName[_i] = _c;
356 }
357 _sensorName[16] = '\0';
358
359 // Determine the short name:
360 for (_i = 0; _i < 11; _i++) {
361 char _c = _sensorData[_i + 29]; // changed from 28 to 29
362 _shortName[_i] = _c;
363 }
364 _shortName[11] = '\0';
365
366 // determine the Units:
367 // units start at 83 for page 1, 102 for p2, and 121 for p3
368 for (_i = 0; _i < 7; _i++) {
369 char _c = _sensorData[_i + 83 + (_page) * 19];
370 _sensorUnits[_i] = _c;
371 }
372 _sensorUnits[7] = '\0'; // add terminating character
373 // Special handling for ISEs, CA, NH4, NO3, or Cl
374 if (_sensorNumber > 37 && _sensorNumber < 42) strncpy(_sensorUnits, "mV ", 7);
375 // Special calibration for Potasium ISE:
376 if (_sensorNumber == 113)
377 strncpy(_sensorUnits, "mV ", 7); // assign name based on sensor number
378
379#if defined DEBUG1
380 Serial.print("_voltageID "); // use this line, if you want to check the autoID voltage
381 Serial.println(_voltageID); // use this line, if you want to check the autoID voltage/*
382
383 Serial.print("sensorData array: "); // only if "#define" is in the code
384 for (_i = 0; _i < 129; _i++) // display whole array
385 {
386 Serial.print(_i);
387 Serial.print(" ");
388 Serial.print(_sensorData[_i]);
389 Serial.print(" ");
390 Serial.println(char(_sensorData[_i]));
391 }
392#endif // DEBUG1
395} // end of AutoID function
396
397float MiniR4VernierLib::readSensor() // This function converts count to sensor reading
398{
399 int _numberAveraged = 10; // number of readings averaged for reading reported
400 int _count;
401 int _sum = 0;
402 float _voltage;
403 byte _buttonState = 0; // condition of button
404 // better code for reading voltage:
405 if (_sensorNumber == 2 ||
406 _sensorNumber == 11) // one of two sensors using the +/- 10 volt line
407 {
408 for (_i = 0; _i < _numberAveraged; _i++) {
409 if (_channel == 1) {
410 _count = analogRead(A1); // read 0 to 5 volt analog lines, Analog 1
411 } else {
412 _count = analogRead(A3); // read 0 to 5 volt analog lines Analog 2
413 }
414 _sum = _sum + _count;
415 } // end of for loop
416 } // end of if
417 else {
418 for (_i = 0; _i < _numberAveraged; _i++) {
419 if (_channel == 1) {
420 _count = analogRead(A0); // read 0 to 5 volt analog lines, Analog 1
421 } else {
422 _count = analogRead(A2); // read 0 to 5 volt analog lines Analog 2
423 }
424 _sum = _sum + _count;
425 } // end of for loop
426 } // end of else
427 _voltage = _sum / _numberAveraged / 1024.0 *
428 5.0; // convert average count to voltage (0 to 5 volt input)
429 _sensorReading = _intercept + _voltage * _slope; // for all linear sensors
430
431 // the code below deals with BTA sensors which have non-linear calibrations
432 // Special calibration for Wide Range Tempeature Sensor(78):
433 if (_sensorNumber == 78)
434 _sensorReading = _intercept + _voltage * _slope + _cFactor * _voltage * _voltage;
435 // Special quadratic calibration for Ethanol Sensor(97):
436 if (_sensorNumber == 97) _sensorReading = _intercept * pow(_voltage, _slope);
437 // Special quadratic calibration for Sound Level Sensor(118)
438 if (_sensorNumber == 118)
439 _sensorReading = _intercept + _slope * _voltage + _cFactor * _voltage * _voltage;
440 // Special calibration for Melt Station(92):
441 if (_sensorNumber == 92)
442 _sensorReading = _intercept + _voltage * _slope + _cFactor * _voltage * _voltage;
443 // Special calibration for ISEs, CA(38), NH4(39), NO3(40), Cl(41):
444 if (_sensorNumber > 37 && _sensorNumber < 42) _sensorReading = (137.55 * _voltage - 168.2);
445 // Special calibration for Potasium(113) ISE:
446 if (_sensorNumber == 113) _sensorReading = (137.55 * _voltage - 168.2); // Potasium ISE
447 if (_sensorNumber == 123)
448 _sensorReading = _intercept + _voltage * _slope + _cFactor * _voltage * _voltage;
449 // Special quadratic calibration for New (Oct. 2016 Thermocouple(123));
450 if (_sensorNumber == 10) // if thermistor:
451 {
452 /* Inputs ADC count from Thermistor and outputs Temperature in Celsius
453 note that this requires: include <math.h>
454 There is a huge amount of information on the web about using thermistors with the Arduino.
455 Here we are concerned about using the Vernier Stainless Steel Temperature Probe TMP-BTA
456 and the Vernier Surface Temperature Probe STS-BTA, but the general principles are easy to
457 extend to other thermistors. This version utilizes the Steinhart-Hart Thermistor Equation:
458 Temperature in Kelvin = 1 / {A + B[ln(R)] + C[ln(R)]3}
459 for the themistor in the Vernier TMP-BTA probe:
460 A =0.00102119 , B = 0.000222468 and C = 1.33342E-7
461 Using these values should get agreement within 1 degree C to the same probe used with
462 one of the Vernier interfaces
463
464 Schematic:
465 [Ground] -- [thermistor] -------- | -- [15,000 ohm bridge resistor] --[Vcc (5v)]
466 |
467 Analog Pin 0
468
469 For the circuit above:
470
471 resistance = ( count*RawADC /(1024-count))
472 */
473 float _logR;
474 float _resistor;
475 float logR;
476 _resistor = 15000; // 15k resistor in series with thermistor
477 long _resistance = (_resistor * _voltage) / (5.0 - _voltage);
478 _logR =
479 log(_resistance); // Saving the Log(resistance) so not to calculate it 4 times later
481 1 / (0.00102119 + (0.000222468 * _logR + (0.000000133342 * _logR * _logR * _logR)));
482 _sensorReading = _sensorReading - 273.15; // Convert Kelvin to Celsius
483 } // end of thermistor code
484
485 _buttonState = digitalRead(12); // button on shield
486 // check if the pushbutton is pressed.
487 // if it is, the buttonState is HIGH:
488 if (_buttonState == LOW) // button down
489 {
490 digitalWrite(13, LOW); // turn on LED on shield
491 Serial.print("V= ");
492 Serial.println(_voltage, 1); // display raw voltage on Serial Monitor
493
494 } else
495 return _sensorReading;
496
497} // END OF Read Sensor
498
499
500void MiniR4VernierLib::DCUPWM(int PWMSetting)
501{
502
503 digitalWrite(6, LOW);
504 digitalWrite(7, LOW);
505 digitalWrite(8, LOW);
506 if (PWMSetting < 0) PWMSetting = 0;
507 if (PWMSetting > 255) PWMSetting = 255;
508 // Serial.print("PWM output set to ");
509 // Serial.println(PWMSetting);
510 analogWrite(9, PWMSetting); // range 0 to 255
511}
512
513void MiniR4VernierLib::DCUStep(int stepCount, int stepDirection, int stepDelay)
514{
515 int DCUStepPattern[4]; // pattern used to drive step motor
516 if (stepDirection == 0) {
517
518 /* The following sequences are for a "normal" step motor.
519 5,9,10,6 steps the motor CW
520 Reverse the order for CCW
521 */
522 DCUStepPattern[0] = 5; // CW
523 DCUStepPattern[1] = 9;
524 DCUStepPattern[2] = 10;
525 DCUStepPattern[3] = 6;
526 } else {
527 DCUStepPattern[0] = 6; // CCW
528 DCUStepPattern[1] = 10;
529 DCUStepPattern[2] = 9;
530 DCUStepPattern[3] = 5;
531 }
532 DCU(0); // Turn off all lines
533 delay(100);
534 Serial.print("step motor rotate for ");
535 Serial.print(stepCount);
536 Serial.print(" steps, in direction ");
537 Serial.print(stepDirection);
538 Serial.print(", with delay of ");
539 Serial.print(stepDelay);
540 Serial.println(" ms");
541 for (int _x = 0; _x <= stepCount; _x++) // set up step pattern
542 {
543 int _output =
544 _x % 4; // % = modulo: returns the remainder of x divided by the value (4) in the case
545 // as "_x" increments "_output" will progress from 0, 1, 2, 3 repeating
546 int _stepValue = DCUStepPattern[_output];
547 DCU(_stepValue); // This points to the case for the DCU. See void DCU below.
548 delay(stepDelay);
549 }; // end of for
550} // end of PWM
551
552void MiniR4VernierLib::DCU(int DCUSetting)
553{
554
555 switch (DCUSetting) {
556 case 0:
557 digitalWrite(6, LOW);
558 digitalWrite(7, LOW);
559 digitalWrite(8, LOW);
560 digitalWrite(9, LOW);
561 break;
562 case 1:
563 digitalWrite(6, HIGH);
564 digitalWrite(7, LOW);
565 digitalWrite(8, LOW);
566 digitalWrite(9, LOW);
567 break;
568 case 2:
569 digitalWrite(6, LOW);
570 digitalWrite(7, HIGH);
571 digitalWrite(8, LOW);
572 digitalWrite(9, LOW);
573 break;
574 case 3:
575 digitalWrite(6, HIGH);
576 digitalWrite(7, HIGH);
577 digitalWrite(8, LOW);
578 digitalWrite(9, LOW);
579 break;
580 case 4:
581 digitalWrite(6, LOW);
582 digitalWrite(7, LOW);
583 digitalWrite(8, HIGH);
584 digitalWrite(9, LOW);
585 break;
586 case 5:
587 digitalWrite(6, HIGH);
588 digitalWrite(7, LOW);
589 digitalWrite(8, HIGH);
590 digitalWrite(9, LOW);
591 break;
592 case 6:
593 digitalWrite(6, LOW);
594 digitalWrite(7, HIGH);
595 digitalWrite(8, HIGH);
596 digitalWrite(9, LOW);
597 break;
598 case 7:
599 digitalWrite(6, HIGH);
600 digitalWrite(7, HIGH);
601 digitalWrite(8, HIGH);
602 digitalWrite(9, LOW);
603 break;
604 case 8:
605 digitalWrite(6, LOW);
606 digitalWrite(7, LOW);
607 digitalWrite(8, LOW);
608 digitalWrite(9, HIGH);
609 break;
610 case 9:
611 digitalWrite(6, HIGH);
612 digitalWrite(7, LOW);
613 digitalWrite(8, LOW);
614 digitalWrite(9, HIGH);
615 break;
616 case 10:
617 digitalWrite(6, LOW);
618 digitalWrite(7, HIGH);
619 digitalWrite(8, LOW);
620 digitalWrite(9, HIGH);
621 break;
622 case 11:
623 digitalWrite(6, HIGH);
624 digitalWrite(7, HIGH);
625 digitalWrite(8, LOW);
626 digitalWrite(9, HIGH);
627 break;
628 case 12:
629 digitalWrite(6, LOW);
630 digitalWrite(7, LOW);
631 digitalWrite(8, HIGH);
632 digitalWrite(9, HIGH);
633 break;
634 case 13:
635 digitalWrite(6, HIGH);
636 digitalWrite(7, LOW);
637 digitalWrite(8, HIGH);
638 digitalWrite(9, HIGH);
639 break;
640 case 14:
641 digitalWrite(6, LOW);
642 digitalWrite(7, HIGH);
643 digitalWrite(8, HIGH);
644 digitalWrite(9, HIGH);
645 break;
646 case 15:
647 digitalWrite(6, HIGH);
648 digitalWrite(7, HIGH);
649 digitalWrite(8, HIGH);
650 digitalWrite(9, HIGH);
651 break;
652 }
653} // end of DCU
654
655float MiniR4VernierLib::readMotionDetector() // This function reads Motion Detector
656{
657 /*
658VernierMotionDetector
659Takes data from a Vernier Motion Detector connected to the Digital 1 connector.
660
661This sketch measures the time taken for the ultrasound to return (in microseconds)
662and then calculates the corresponding distance (based on the speed of ultrasound
663in air) and displays the distance (in cm) on the Serial Monitor.
664
665Here is how the Vernier Motion Detector works:
666- when pin 2 on BTD is pulled high, this triggers the ultrasound pulse
667- the program then starts timing but then delays 0.9 ms *(blanking time,
668 0.9 seconds is the time it takes ultrasound to travel 15 cm twice (round trip))
669- the program then monitors pin 1 on the BTD, waiting for it to go high.
670This happens when an echo is detected.
671
672See www.vernier.com/arduino for more information.
673 */
674
675 long _time; // clock reading in microseconds
676 long _duration; // time it take echo to return
677 int _val = 0;
678 digitalWrite(3, LOW);
679 delayMicroseconds(4000);
680 digitalWrite(3, HIGH); // start the ultrasound pulse using Trigger Pin 3
681 _time = micros(); // note time
682 delayMicroseconds(900); // delay during the blanking time
683 do {
684 _val = digitalRead(2); // read echo pin 2
685 // if no echo, repeat loop and wait:
686 } while (_val == LOW);
687 _duration = micros() - _time;
688 /* The speed of sound is 340 m/s.
689 The ultrasound travels out and back, so to find the distance of the
690 object we take half of the distance traveled.*/
691 _distance = _duration * 340 / 2 /
692 10000; // note the 340 is the speed of sound in m/s. note convert to cm
693 return _distance;
694}
Handling MiniR4.Vernier functions.
void DCUStep(int stepCount, int stepDirection, int stepDelay)
void DCUPWM(int PWMSetting)
void DCU(int DCUSetting)