|
Main /
ArduinoMiniOn this page... (hide)
The Arduino Mini 1. Use of ArduinoSince we already have a fast computer on our 'bot, the Arduino isn't necessarily needed, but we added it because it brings on-board D/A converters and ease of hardware integration. We also thought it would make a good exercise in using multiple computers and syncing data between them 2. Programming2.1 Shaft EncodersThe primary purpose of the Arduino is to provide an interface to the optical encoders. Initially, we thought it would be easiest to create an interrupt on a rising edge of the phototransistor, but since the fully-saturated output of the element is only about 0.5 V - well below the interrupt threshold - we decided to just use one of the on-board D/A lines and continuously poll it. We attached the output of the phototransistor to the analog input pin 3. In order to detect the rising edge of the output, we had to come up with a bit of logic, as such: int analogPin = 3; int val = 0; // variable to store analog value read int alreadyHigh = 0; int i; // looper unsigned long startTime, totalTime; int count, totalCount; void setup() // empty { } void loop() { startTime = millis(); count = 0; for (i = 0; i < 1000; i++) { val = analogRead(analogPin); // read the input pin if (val > 410) { if(!alreadyHigh) { alreadyHigh = 1; count++; } } else if (alreadyHigh) { alreadyHigh = 0; } } totalTime = millis() - startTime; totalCount = count; } This sets two variables at the end of every loop:
It should be noted that 2.2 I2C on the MiniI2C is available on the Arduino mini by way of the Wire To summarize:
Of course, there is a great reference for all the Arduino-specific commands at the Arduino Extended Reference Adding I2C functionality, we came up with: #include <Wire.h> #define ADDRESS 32 #define C_REG 0 #define T_REG 1 #define THRESHOLD 410 int toSend = 0; int analogPin = 3; int val = 0; // variable to store analog value read int alreadyHigh = 0; int i; // looper int startTime, stopTime, totalTime; int count, totalCount; void setup() { Wire.begin(ADDRESS); // join i2c bus with address #32 Wire.onRequest(requestEvent); // register event Wire.onReceive(receiveEvent); // register event Serial.begin(9600); // start serial for output } void loop() { startTime = millis(); count = 0; for (i = 0; i < 1000; i++) { val = analogRead(analogPin); // read the input pin if (val > THRESHOLD) { if(!alreadyHigh) { alreadyHigh = 1; count++; } } else if (alreadyHigh) { alreadyHigh = 0; } } stopTime = millis(); totalTime = stopTime - startTime; totalCount = count; } // function that executes whenever data is requested by master // this function is registered as an event, see setup() void requestEvent() { Wire.send(toSend); } // function that executes whenever data is received from master // this function is registered as an event, see setup() void receiveEvent(int howMany) { while(1 < Wire.available()) // loop through all but the last { char c = Wire.receive(); // receive byte as a character } int x = Wire.receive(); // receive byte as an integer switch(x) { case C_REG: toSend = totalCount; totalCount = -1; // reset break; case T_REG: toSend = totalTime; totalTime = -1; // reset break; default: // Bad/Empty register toSend = -1; // reset break; } } This creates two registers that can be read from the board
It takes about 100 microseconds to perform an analog read on the Arduino. In practice, we take 1,000 readings (as defined in the |