Project Summary
Using an Arduino Uno, my code should poll pin 13's state while waiting for an external button to deliver 5v which then initiates a loop that constantly polls pin 2's state at 40hz. Each time the state changes at Oin 2, a counter is increased.
**Problems needing to be solved in order of importance. **
When I press the external button, 5v is sent to the Arduino pin 13. This initiates the loop BUT as long as the button is pressed the voltage is constant causing the serial monitor to be populated at an insanely high rate instead of at 40hz. How can I make the button press start the loop without being affected by the length of the button press?
Is there any way I can improve the synchronicity of the printing? It is SLIGHTLY slower than 40hz and will be off by a couple of seconds (4ish) after an hour of recording.
I am currently solving bouncing issues after the fact in my spreadsheet as Delay functions will likely cause my polling to get off sync with my spectrometer.
**More details if needed. **
I am a scientist interested in neurotransmission during physical activity. I have created a tachometer (mouse running wheel, schematic below) with a reed switch (COM-10601 ROHS, Sparkfun) connected to pin 2 (internal pullup) and ground pin. Each time a magnet passes by the switch, the count should rise by 1 (in actuality, the reed switch bounces and counts multiple times). I am simultaneously running another machine (spectrometer) that measures the levels of a neurotransmitter at 40 HZ (25 milliseconds). The goal is to correlate the speed of the wheel with the level of neurotransmitter so I will combine the data by fixing time in column A, the level of the neurotransmitter in column B, and the serial monitor data from the reed switch counting in column C (example attached).
Here is my code:
volatile long frame = -1;
volatile int rotations;
int trigger = 0;
int triggerPin = 13; //the pin that the external trigger is attached to
int wheelPin = 2; //the pin that the Reed Switch is attached to
int wheelPin_irq = 0; //IRQ that matches to pin 2
const unsigned long eventInterval = 25; //Hopeful sampling rate (40HZ)
volatile unsigned long previousTime = 0;
void setup() {
Serial.begin(115200);
pinMode(triggerPin, INPUT_PULLUP);
pinMode(wheelPin, INPUT_PULLUP);
attachInterrupt(wheelPin_irq, IRQcounter, RISING);
}
void IRQcounter() {
rotations++;
}
void loop() {
trigger = digitalRead(triggerPin);
if (trigger == HIGH) {
frame = 0;
}
while ( frame>=0 ) {
unsigned long currentTime = millis();
if ( currentTime - previousTime >= eventInterval) {
Serial.print(currentTime);
Serial.print("\t");
Serial.println(rotations);
previousTime += eventInterval;
frame = frame +1;
}
}
}
Thank you for any and all help. Those that help us rookies solve these problems are absolute life savers!!
Uhhh... pin 13 is also the on-board LED, so you might try a different pin. Also, I see no ground connection to your external trigger, so how does the Arduino know when there is no external 5 volts?
Paul
It looks like you want a change from 0 to 5V on pin 13 to start the test. Your schematic suggests it has to remain pressed to power/trigger the spectrometer. What stops the test? Is the button a latching type (press-on, press-off)?
'frame' does not look like it gets reported out; why track/increment it?
Paul_KD7HB - I will move in the input from 13 to 12 (like in my fritz). I will also add in a connection to ground in that wire. I assume I should put in a resister too?
Railroader - You made me laugh out loud. I thought my fritzing was pretty. I can upload a circuit diagram, but I think the point is made already for this post. Blackfin is right, I am using pin 2.
Blackfin - Once the button is pressed once, the test should run forever. I manually stop the test in Arduino by reuploading the code and by stopping recording in my Spectrometer program. This really isn't a problem, so I did not waste time making code. I am incredibly new (this is my first project) so I am trying to go simple haha. I am not sure about the frame... thought it would be needed - I will try to remove it!
ayland:
Thanks all for the replies so far! No problem. We work for free.
Paul_KD7HB - I will move in the input from 13 to 12 (like in my fritz). I will also add in a connection to ground in that wire. I assume I should put in a resister too? Not needed when using INPUT_PULLUP.
Railroader - You made me laugh out loud. I thought my fritzing was pretty. I can upload a circuit diagram, but I think the point is made already for this post.
You think.... Every member asking questions is thinking that they are thinking and the mistakes are usual. Such an easy thing as how, from where, power is supplied is a usual reson for trouble, and hided behind a beautiful sails picture. What I write to You I hope more members will read. Engineering calls for drawings and is very often needed.
I manually stop the test in Arduino by reuploading the code Press the reset button instead! The number of code loadings to the controller is generous but not unlimited.
Railroader: I hear you - this is importnat. I will work a schematic up. And that is good to know!
Blackfin: Woah, this is awesome! Thanks! I plugged copied in the code - 1. The timing seems to work great! 2. The code starts automatically without pressing the external trigger button (I detached the wire to make sure something screwy wasn't going on, and the code still ran without pressing it).
ayland:
Railroader: I hear you - this is importnat. I will work a schematic up. And that is good to know!
Blackfin: Woah, this is awesome! Thanks! I plugged copied in the code - 1. The timing seems to work great! 2. The code starts automatically without pressing the external trigger button (I detached the wire to make sure something screwy wasn't going on, and the code still ran without pressing it).
(i.e. add an initialization of lastTrigger by reading triggerPin) does that make a difference?
Can you verify your trigger pin switch wiring? You press the button to apply 5V to the pin; how is the pin controlled when the button isn't pressed? You initialize the pin mode as INPUT_PULLUP so if you have a pull-down resistor present you could have indeterminant voltage present on the pin due to a voltage-divider.
It'd be better if you could change the button wiring so that when the button is not closed, the switch is open and the pin idles "high" thanks to the INPUT_PULLUP mode; the other side of the switch is connected to GND so when the button is pressed the pin is grounded and you look for the high-to-low transition.
Pls verify: the spectrometer is triggered by the button press giving 5V to a "TRIG" input to the spectrometer?
Sorry for the late reply, I had to switch to a different task for a bit.
~~When I plug in your new startup code, Blackfin, pressing the external trigger no longer starts the Arduino code. Of note, if I connect the voltage from the external button directly to pin 13, the LED turns on whenever I press the button (and stays on if held). Pressing this button no matter what the code is will always turn on my spectrometer as the button is essentially part of the spectrometer. ~~ E*dited after post as this comment was incorrect due to an error on my end. *
I have a long insulated wire coming straight from my external trigger that inserts directly into the Arduino pin #13 (or 12.. as I tried both in accordance with Paul_KD7HB's advice).