Timeline for Delay between multiple analogReads
Current License: CC BY-SA 3.0
18 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jan 24, 2017 at 10:53 | comment | added | Isra | @frarugi87 I did what you suggested, it turned out that I have to print the readings each in a single line (from Arduino), Matlab couldn't see the terminator (line end). Another issue, when reading the time in Matlab, you have to use fscanf(s,%f) instead of fscanf(s,%d) because it's a double number. Thank you all for your MASSIVE support and I hope this helps others as well! | |
Jan 24, 2017 at 9:20 | comment | added | frarugi87 | @Isra try to use a step by step approach: first open and read only the strings you receive (with fscanf(s)), then read the integer value and finally convert and use it. See when you block and try to find a solution (I'm not very much into matlab's serial port interface, so I don't know how to debug it properly). As for the 10 bits, well you are printing to serial, so the value you receive (for instance 1001) is transferred in ascii coding "1001", so four bytes ('1', which is 49, '0', which is 48, then '0' and '0'). If the error is the speed try lowering it to 100Hz (set the define to 10000) | |
Jan 24, 2017 at 9:16 | comment | added | Isra | @EdgarBonet Thanks very much, I tried it but I still get the same error: "Warning: Unsuccessful read: The input buffer was filled before the Terminator was reached.. " I've tried reading the pins with the regular rate and I was able to read it in matlab. This error shows up only when I set the rate to 1kHz. | |
Jan 24, 2017 at 9:10 | comment | added | frarugi87 | @EdgarBonet I already noticed that, and fixed it as you fixed before writing the comments, but maybe I made a mess with the back button in the browser and the old version remained online. Thank you for fixing it... | |
Jan 24, 2017 at 9:07 | comment | added | Edgar Bonet |
While replacing millis() with micros() , you introduced an erroneous division by INTERVAL_LENGTH_US . I took the liberty to edit your code to restore its previous logic, which was good. Note that the test if (((currentMicros - previousMicros) / INTERVAL_LENGTH_US) > 0) is not technically wrong, and the compiler would optimize it into if (currentMicros - previousMicros >= INTERVAL_LENGTH_US) anyway. But I think it's clearer without the division. @Isra: you may try this new version.
|
|
Jan 24, 2017 at 9:06 | history | edited | Edgar Bonet | CC BY-SA 3.0 |
Removed erroneous division by INTERVAL_LENGTH_US.
|
Jan 24, 2017 at 9:04 | comment | added | Isra | thank you @frarugi87 for pointing that out, I fixed it. But when I read the serial data in matlab, it gives me this error "Warning: Unsuccessful read: A timeout occurred before the Terminator was reached.. " Do you have an idea on why is that happening? I'm using fscanf(s, '%d')*(5.0 / 1023.0)); to read the values. One last point, if the analog readings are 10 bits wide, how is that transmitted ? I know serial communication's data width is only 8 bits (I set the baud rate to 250000 on both ends just in case) | |
Jan 24, 2017 at 8:26 | comment | added | frarugi87 | @Isra please update the code with the one in the answer, since it fixes Edgar's issue. This one is a bit more flexible than the previous one and updates exactly (well, more exactly than millis) every ms. As for matlab, the data source is the same, so the speed is the same, provided that matlab is fast enough to read all the data | |
Jan 24, 2017 at 8:24 | comment | added | frarugi87 | @NickGammon I read a lot of wonderful replies on SO and here by you, but I didn't know you had a forum where you put a lot of things. Thank you for your link: I'll read your website | |
Jan 24, 2017 at 8:22 | comment | added | frarugi87 |
@EdgarBonet I make a (quick) search on google and couldn't find this behavior, so I tested it and... Well, 42 can be the Ultimate Answer to Life, The Universe and Everything, but not for millis ... Thank you for pointing this out: I updated the answer with the code I think fixes this (so micros() / prescaler)
|
|
Jan 24, 2017 at 8:16 | history | edited | frarugi87 | CC BY-SA 3.0 |
Corrected according to Edgar's remarks
|
Jan 24, 2017 at 5:03 | comment | added | Nick Gammon♦ | @frarugi87 Edgar Bonet is right, I cover this issue here. As Edgar said, because of the timer prescaler, the millis "tick" is actually slightly slow. The code adjusts for that every 41/42 updates. | |
Jan 24, 2017 at 4:33 | comment | added | Isra | @frarugi87 I tried your code and it's working! I needed a way to fix my sampling rate and this does it. As you said, the baud rate doesn't affect anything. I tried 9600 and 250000 and both gave me 1kHz. Recieving the readings in Matlab instead of the serial monitor won't affect the frequency right? | |
Jan 24, 2017 at 4:16 | vote | accept | Isra | ||
Jan 23, 2017 at 21:20 | comment | added | Edgar Bonet | On the 16 KHz AVRs, the millis counter is updated every 1024 µs: the millisecond count is incremented by one and the fractional count is incremented by 3 125ths of a millisecond. Whenever this fraction reaches a full millisecond, the millisecond count is incremented by two instead of one. This happens roughly once every 1000/24 ≈ 41.67 updates. | |
Jan 23, 2017 at 20:55 | comment | added | frarugi87 | @EdgarBonet this sounds new to me... What are the cases when it skips (apart from when your loop code actually is longer than 1ms)? | |
Jan 23, 2017 at 20:52 | comment | added | Edgar Bonet |
Note that millis() sometimes skips a millisecond, e.g. it jumps from 41 straight to 43. You can use micros() instead of millis() to avoid the problem: it gives a 4 µs resolution.
|
|
Jan 23, 2017 at 11:38 | history | answered | frarugi87 | CC BY-SA 3.0 |