I am working on making small datalogger that is used to save data for some time lets say 2-5 sec and at the same time for that specific task gpio must be doing something else.
My code is down below for your refernce, I am trying to read IMU data for 2 sec and i want that during the two seconds I can do other work like turning on LED or anyother gpio based task. But whats actually happening is that inside the loop, both delays are separate. First it receives data and then it do some delay. I have found yield() funtion is one when called can do backend processing while delay is also being called but i dont understand how to incorporate in my program. I could not load yield based examples to understand as I have UNO and teensy3.6 with me.
Both are not running when tried to run the basic example of yield function available at arduino forum.
Please someone explain or point some useful link where i can relate on how to include delay and while delay in progress I read sensor values and print them on serial or store in SD-card.
Thank you
Device: Teensy3.6
IMU sensor using I2C
#include <Wire.h>
#include "BN55.h"
#define White 35
#define Yellow 36
#define Red 37
#define A 0X28
BN55 mySensor(A);
void setup()
{
Wire.begin();
Serial.begin(9600);
while (!Serial)
{
; // wait for serial port to connect. Needed for native USB port only
}
pinMode(Yellow, OUTPUT);
pinMode(White, OUTPUT);
pinMode(Red, OUTPUT);
digitalWrite(Yellow, LOW);
digitalWrite(White, HIGH);
digitalWrite(Red, HIGH);
mySensor.init();
}
void loop()
{
Serial.println("Press any key to continue...");
while (Serial.available())
{
Serial.read();
}
while (!Serial.available());
Serial.println("Initializing...");
delay(500);
digitalWrite(White, LOW);
Serial.println("Focus time");
delay(2000);
digitalWrite(Red, LOW);
Serial.println("starts");
for(int k=0; k<5; k++)
{
mySensor.readAccel();
Serial.print("X (mg): "); Serial.print(mySensor.accel.x); Serial.print(" Y (mg): ");
Serial.print(mySensor.accel.y); Serial.print(" Z (mg): "); Serial.println(mySensor.accel.z);
delay(500);
}
//yield();
delay(5000);
RESET();
delay(500);
Serial.println("\r\nT H E E N D \r\n");
}
void RESET()
{
digitalWrite(White, HIGH);
digitalWrite(Red, HIGH);
}
yield() doesn't produce any reliable delay. If you try to use it on an UNO, then there's no delay at all since the UNO doesn't have any other threads that could run during that time.
@Power_Broker I understand this basic kind of delay and how millis function run inside the delay function. I dont have any problem to use delay function, I want to use delay while doing some other subroutine or task while delay is called and while reading yield function, i think of it as something that can run any subroutine or task while delay is in progress. So, I'm wondering how to use yield and delay both to complete my task.
@MorganS I am not using yield to make any delay. And second I'm using teensy3.6 for my task. UNO was just to check how yield() works but couldn't get any results. So, I'm sticking onto teensy3.6
For all those who are not clear about my question, I want to do some data logging of sensor while having some delay. In future i have to incorporate other thing in delay so for now I just want to learn how can I run any loop or subroutine while delay is called. If you have any other suggestion let me know. yield() was just something I saw in SD library which I think to use but have never use this function before so I have no idea how to perform my said task.
Yield can only be used on the more advanced processors. Arduino DUE and upwards. Of course it doesn't work on an UNO.
Yield only does something if you're using multi-threading. That's extremely rare on Arduinos, because most of us don't have anything more advanced than an UNO. All the examples I've seen online are trivial and didn't need to use yield() anyway.
If you're using delay() then you're using it wrong. That's only a simple helper function for highschool kids to get their traffic-light projects flashing. Any serious Arduino program will not use delay().
RakehSheikh:
I want to use delay while doing some other subroutine or task while delay is called
Then why use delay() in the first place?
RakehSheikh:
For all those who are not clear about my question, I want to do some data logging of sensor while having some delay
Why not log the data without delay()? You can still do other things inside the loop (like lighting LEDs) while datalogging. It's better to practice good embedded systems programming techniques than forcing yourself to work around the delay() function.
RakehSheikh:
In future i have to incorporate other thing in delay
yield() is sort of the opposite of delay(). The idea behind yield() is that it allows code that must be run frequently to work in conjunction with blocking code. delay() itself calls yield(). You also might want to call yield() from any code of your own that is blocking. The hope is that blocking library code will also call yield(), though that guideline is probably followed quite inconsistently in 3rd party libraries.
MorganS:
Of course it doesn't work on an UNO.
It does indeed work on the Uno. Here's a demonstration:
Thanks for letting me know about the Fiber library.
And sir I have to capture images for 3 seconds and in 3 seconds I have to read data and log it. So u can relate both are performed in that specific time duration. That's the reason for making delay in the first place using delay() but looking into the other forum suggested upwards, i think i can do this maybe by some other way. But still hope to make it work.
No need to apologize, we all here to learn.
P.S: I'm using TEENSY3.6 not UNO please re-read it. UNO was just to test yield() which I got it it doesn't work but does it work with teensy3.6 ?
Arduino: 1.6.13 (Windows 10), TD: 1.35, Board: "Arduino/Genuino Uno"
WARNING: library Scheduler claims to run on [sam] architecture(s) and may be incompatible with your current board which runs on [avr] architecture(s).
C:\Users\x\AppData\Local\Temp\ccUYjmGk.s: Assembler messages:
C:\Users\x\AppData\Local\Temp\ccUYjmGk.s:525: Error: constant value required
lto-wrapper: C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-gcc returned 1 exit status
c:/program files (x86)/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld.exe: lto-wrapper failed
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino/Genuino Uno.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
I have solved the problem of delay with the help of millis function that seems quite easy compared with the fiber library function. Everything was running okay with getting data and storing unless i noticed that I can save upto 100 files only and tried to increase the number of size but is not making right files.
char filename[] = "Logger00.txt";
for (uint8_t i = 0; i < 100; i++)
{
filename[6] = i / 10 + '0';
filename[7] = i % 10 + '0';
if (! SD.exists(filename))
{
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile)
{
Serial.println("Error: Log file could not created");
}[CODE]
The above code only make 100 files but when I tried to increase no. of files by adding like this,
[CODE]char filename[] = "Logger000.txt";
for (uint8_t i = 0; i < 100; i++)
{
filename[6] = i / 100 + '0';
filename[7] = i / 10 + '0';
filename[8] = i % 10 + '0';
if (! SD.exists(filename))
{
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile)
{
Serial.println("Error: Log file could not created");
} [CODE]
It makes files but after 100 it saves them as logger1:1.txt, logger1:2.txt,1:3.. logger1:9.txt and after this files it does no make txt file. Can someone point out what I'm doing wrong ?
Thank you for your previous replies and suggestions
-Rakeh
I tried changing type from uint8_t to uint16_t and also tried fitting the characters in 8 but both ways same result. When it increases from 99 the middle digit i.t 100 or 101, zero changes to : and when it increases from 109 to 110. It gives me the error saying logfile not created.
And while posting code i forgot to change limit which is in my loop was 200. I put wrong here but in the code, I write just okay but getting again error..
Either way, I think there is a better way to convert the index counter to a series of chars. Think about it, what if you have 110? What would filename[6] through filename[8] be?
RakehSheikh:
And while posting code i forgot to change limit which is in my loop was 200. I put wrong here but in the code, I write just okay but getting again error..
Thank you @Power_Broker for giving me the hint. My end task is to set the limit for maybe 10k files or 5k but more than 1000 atleast. I will try to modify the code as u mentioned and will post the results.
Power_Broker:
(although there is probably an even better way):
If you have any other suggestion on simple way, please let me know.. Thank you
Below is the correct code with the modification that I have made. Thank you for helping all of you. It is working fine for more than 100 but I have to test it for large no. of files as I mentioned above maybe 1000 or more. So i'll work on the code to make that. Meanwhile if any of you have any idea to generate the files but with simple logic would be highly appreciated.
Thanks
-Rakeh
char filename[] = "Loggr000.txt";
for (uint32_t i = 0; i < 200; i++)
{
byte Hun = i/100;
filename[5] = i / 100 + '0';
filename[6] = (i - Hun *100) / 10 + '0';
filename[7] = i % 10 + '0';
if (! SD.exists(filename))
{
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}[CODE]