Phil Grant | 10/10/2018 20:46:49 |
107 forum posts 21 photos | I've had a look at some old code that I used that used interrupts and as I can see you setup the interrupts in the setup part of the code attachInterrupt(0, Start, FALLING); 0 = pin 2, 1 = pin 3, "start" and "stop" are the names of the functions that get called when the interrupts are triggered and the falling indicates that the level goes from high to low to trigger the interrupt.
|
Peter Bell | 10/10/2018 22:49:53 |
399 forum posts 167 photos | Thanks for the replies, very helpful. This is part of the code that I want count with from the sensor. It will eventually have more zones and successfully looped using the small delay when I tried it on my breadboard. It is my first attempt with Arduino and although I'm sure it could be improved no end I was pleased to get it running with some help from a friend. Due to bringing the wrong memory stick with me I do not have the version where I tried incrementing using attached interrupt, sorry. I did think that perhaps I should practice adding attached interrupt to blink as pratice when I return? #include <Wire.h> // Comes with Arduino IDE lcd. clear();
|
duncan webster | 10/10/2018 23:01:44 |
5307 forum posts 83 photos | Posted by Phil Grant on 10/10/2018 20:46:49:
I've had a look at some old code that I used that used interrupts and as I can see you setup the interrupts in the setup part of the code attachInterrupt(0, Start, FALLING); 0 = pin 2, 1 = pin 3, "start" and "stop" are the names of the functions that get called when the interrupts are triggered and the falling indicates that the level goes from high to low to trigger the interrupt.
I think to comply with preferred method this should be attachInterrupt(digitalPinToInterrupt(2), Start, FALLING); attachInterrupt(digitalPinToInterrupt(3), Stop, FALLING); |
Phil Grant | 10/10/2018 23:08:43 |
107 forum posts 21 photos | Posted by duncan webster on 10/10/2018 23:01:44:
Posted by Phil Grant on 10/10/2018 20:46:49:
I've had a look at some old code that I used that used interrupts and as I can see you setup the interrupts in the setup part of the code attachInterrupt(0, Start, FALLING); 0 = pin 2, 1 = pin 3, "start" and "stop" are the names of the functions that get called when the interrupts are triggered and the falling indicates that the level goes from high to low to trigger the interrupt.
I think to comply with preferred method this should be attachInterrupt(digitalPinToInterrupt(2), Start, FALLING); attachInterrupt(digitalPinToInterrupt(3), Stop, FALLING); Yes you are right, but on a nano it compiles and works fine using int.0 and int.1. |
Peter Bell | 11/10/2018 08:57:51 |
399 forum posts 167 photos | Looks like interrupt is being well covered thanks. Unfortunately Unable to try anything at present but looking forward to it The other method mentioned by Dave is “spin digitalRead() in a loop” Perhaps that could be an alternative as once the code has been activated by an impulse it runs then just sits waiting for the next pulse.Is there an example of that somewhere? That would help—-thanks Peter
|
Peter Bell | 11/10/2018 09:27:33 |
399 forum posts 167 photos | Forgot to say that the input is pretty slow, between 0–5hz |
Phil Grant | 11/10/2018 09:34:12 |
107 forum posts 21 photos | I have some code that I wrote for an air rifle chronograph that detects a pellet breaking a beam then measuring the time taken before the second beam is broken then sending the time via bluetooth. This code basically sits waiting for a pin to be triggered then does something then goes back to wait a again, you could probably adapt t his code, it's very simple really. I have details on my blog here www.gadjet.co.uk Edited By Phil Grant on 11/10/2018 09:34:40 |
Phil Grant | 11/10/2018 10:01:03 |
107 forum posts 21 photos | My chronograph code is measuring events around 200uS apart so it should be more than capable enough. |
SillyOldDuffer | 11/10/2018 11:41:37 |
10668 forum posts 2415 photos | Well here's Pete's code modified to increment count whenever pin 3 is grounded. Bit more complicated that it should be because I use a different version of the LiquidCrystal library and only have a 20x4 display. Testing by tapping a lead from pin 3 to ground. It works, but as noted in the code, it detects contact bounce galore! Debouncing is a separate issue and, as the best way of fixing it depends on Pete's input circuit, I won't cover it in this post. #include <Wire.h> // Comes with Arduino IDE
Edited By SillyOldDuffer on 11/10/2018 11:51:36 Edited By SillyOldDuffer on 11/10/2018 11:52:51 |
Phil Grant | 11/10/2018 17:26:30 |
107 forum posts 21 photos | Just for interest I discovered a link to a site that uses blockly to graphically code for Arduino and other languages, this could be very useful for those not confident in using the Arduino IDE C code editor, this basically creates the code by dragging graphical block onto a sheet as required then paste to code into the Arduino IDE. To use the editor click on the US flag on the left under 'blocklyduiuno" |
Peter Bell | 11/10/2018 21:34:01 |
399 forum posts 167 photos | Dave, Many Thanks for adding the code and explanations, just trying to work my way through them on a WiFi hotspot thats worse than dial up used to be. At present it wont verify with a mysterious message (at least to me!) "of expected ' Phil, thanks for the blockly info, never heard of that for Arduino before--I'll explore. Not sure where all the smileys came from though. Peter |
SillyOldDuffer | 12/10/2018 09:31:52 |
10668 forum posts 2415 photos | Posted by Peter Bell on 11/10/2018 21:34:01:
... At present it wont verify with a mysterious message (at least to me!) "of expected ' ... Not sure where all the smileys came from though.
Hi Peter, It's the curse of the smileys. The forum's editor 'helps' by converting the character strings once used to make text smileys and the like into emoticons. In the good old days before graphics a winky was a colon followed by a right bracket. Trouble is these combinations appear in computer source. As the editor also applies other officious format rules (like removing white-space on the left), it's hard to publish computer source code without having it subtly mangled! Here's a dropbox link to the code I ran on my Nano. Note that you need to get rid of the changes I made to suit my particular version of LiquidCrystal which differs in the way displays are initialised. Dave
|
Neil Wyatt | 12/10/2018 14:23:31 |
![]() 19226 forum posts 749 photos 86 articles | Posted by SillyOldDuffer on 12/10/2018 09:31:52:
It's the curse of the smileys. The forum's editor 'helps' by converting the character strings once used to make text smileys and the like into emoticons. I Sadly, it appears to be spreading to other forums Neil |
Mark Rand | 12/10/2018 18:38:41 |
1505 forum posts 56 photos | That's alright. Just use uuencode Edited By Mark Rand on 12/10/2018 18:40:57 |
Peter Bell | 12/10/2018 21:58:48 |
399 forum posts 167 photos | Hi Dave, I must admit I thought that cut and past was just that, never realised what the editor was doing by tangling things around like that, another lesson learned. The drop version works perfectly once I restored my lcd so many thanks for your help, still untangling what its all doing but its great to be learning and making progress at the same time. The switch bounce is horrendous but at least the serial numbers agrees with the lcd. The software solutions look very involved in the versions found so far so I'll try adding some r&c to see that the effect is. It may be ok in real life as I'm using a proximity sensor but I dont know what the rise time is yet. You mentioned earlier "spin digitalRead() in a loop until a pulse is detected, then count it." as an alternative to attachinterrupt, could you point me to some info on it? Thanks Peter
|
Phil Grant | 13/10/2018 10:57:22 |
107 forum posts 21 photos | Posted by Peter Bell on 12/10/2018 21:58:48:
You mentioned earlier "spin digitalRead() in a loop until a pulse is detected, then count it." as an alternative to attachinterrupt, could you point me to some info on it? Thanks Peter
Peter, Here is some code I wrote to check for a pin going low then counting microseconds before another pin goes low and then sending the value out over serial. This code sits in the "wait state" (Spinning?) until the pin goes low it then changes to another "monitor state" Please ask any questions you might have, I hope this is sort of what you're after. /*
Sketch to measure the time in uSeconds between two IR sensors being triggered
and sending the result to the serial port.
Use with the PC application to display results
Version 1.00
Phil 25/04/13
*/
#define Trip_in_1 2 //set light Trigger 1 to pin D2
#define Trip_in_2 3 //set light Trigger 2 to pin D3
#define WAIT_STATE 0
#define MONITOR_STATE 1
#define OUTPUT_STATE 2
unsigned long Trigger_1 = 0;
unsigned long Trigger_2 = 0;
volatile unsigned int current_state = WAIT_STATE;
char my_oldSREG; //to hold status register while ints are disabled
unsigned long SensDist = 196850; //Distance between sensors in feet *1000000 60mm
unsigned long duration = 0; // time between triger 1 and 2
volatile boolean is_timeout = false;
void setup () {
//Serial.begin(38400);
Serial.begin(9600); // for raw un programmed BT board
Serial.println("Chrono SW Ver 1.00"
![]() pinMode(Trip_in_1, INPUT);
pinMode(Trip_in_2, INPUT);
digitalWrite(Trip_in_1, HIGH); //turn on pullup resistor
digitalWrite(Trip_in_2, HIGH);
reset_variables();
}
void loop () {
switch (current_state) {
case WAIT_STATE:
if(digitalRead(Trip_in_1)==LOW) {
Trigger_1 = micros();
current_state = MONITOR_STATE;
}
break;
case MONITOR_STATE:
while(digitalRead(Trip_in_2)==HIGH); //loop until the Trigger goes LOW && !is_timeout
if(!is_timeout)
Trigger_2 = micros();
current_state = OUTPUT_STATE;
break;
case OUTPUT_STATE:
//if (Trip2 > Trip1) {
output_serial_info();
reset_variables();
current_state = WAIT_STATE;
//}
break;
}
}
void output_serial_info() {
// Serial.print("Duration\t"
![]() Serial.println((Trigger_2 - Trigger_1));
//Serial.println(" uS"
![]() }
void reset_variables() {
Trigger_1 = 0;
Trigger_2 = 0;
//is_timeout = false;
}
Edited By Phil Grant on 13/10/2018 10:58:15 |
SillyOldDuffer | 14/10/2018 17:15:04 |
10668 forum posts 2415 photos | Posted by Peter Bell on 12/10/2018 21:58:48:
Hi Dave, ...You mentioned earlier "spin digitalRead() in a loop until a pulse is detected, then count it." as an alternative to attachinterrupt, could you point me to some info on it? Thanks Peter
Hi Peter, I've modified your code to show how it's done. It's on Dropbox. Phil's example is more complicated because it does some software debouncing as well. Depending on the application, it's often easier to provide hardware debouncing. The simplest method is just to put a capacitor (about 100nF not critical) across the switch contacts. It prevents 'FALLING' or 'LOW' being detected until the switch has been held down for several milliseconds, which tends to eliminate bounce. For more demanding applications you could wire up an NE555 as a debouncer, or a comparitor, - even better - a Schmitt Trigger chip. Much depends on what you're doing and how bad the switch is. A very simple software debouncer might change the spin loop in the example based on your code to look like this: // Spin waiting for input while ( true ) { All it does is insist on two reads detecting LOW inside a time window before counting. Debouncing is such a common problem that there are a few Arduino libraries in the Library Manager to provide software debouncing. I've tried Bounce2 - it's much smarter and more general than my simple example, for example it can manage several switches, but you might prefer one of the others. Bit of a learning curve with them. Dave
Edited By SillyOldDuffer on 14/10/2018 17:15:43 |
Neil Wyatt | 14/10/2018 17:48:45 |
![]() 19226 forum posts 749 photos 86 articles | My preferred way of dealing with bounce is to use interrupt routines to set a flag and not re-enable them until I've dealt with the switch routine. This enables me to deal with inputs when and where I want to without affecting time-critical processes with long interrupt routines. If you use inline switch detections, it's usually easiest to plan your code so you don't test for a second switch condition twice within the bounce period. Neil |
Peter Bell | 14/10/2018 20:47:58 |
399 forum posts 167 photos | Hi Dave, Thanks for all that, your description on debounce sounds logical. Yes a 100nf almost fixes it, adding a 1k resistor in series completely cures it as far as I can see. I'll have a look at the bounce libraries, a quick search reveals a lot to choose from. Thanks also for the spin, makes sense apart from the syntax I'm afraid. The curly brackets with the semicolon inside are used to end a statement according the reference? { ; } I'm sure there's a simple explanation! // Spin waiting for input while ( digitalRead( switch1 ) == HIGH ) { Also adding a LOW digital read version first stops it just rolling through so that it increments each complete input cycle, what is the advantage of interrupt which (to me!) appears to be doing the same job? Peter
|
Peter Bell | 14/10/2018 20:49:03 |
399 forum posts 167 photos | Thanks Neil, I'll have to work on that one once I get my head around the present learning! Peter |
Please login to post a reply.
Want the latest issue of Model Engineer or Model Engineers' Workshop? Use our magazine locator links to find your nearest stockist!
Sign up to our newsletter and get a free digital issue.
You can unsubscribe at anytime. View our privacy policy at www.mortons.co.uk/privacy
You can contact us by phone, mail or email about the magazines including becoming a contributor, submitting reader's letters or making queries about articles. You can also get in touch about this website, advertising or other general issues.
Click THIS LINK for full contact details.
For subscription issues please see THIS LINK.