I want to use an SQ11 camera with arduino. To do this I am triggering it by attaching a wire to power on switch of the camera with A1 pin of my Nano 33 BLE. The delay code works perfectly, but I want to implement the same without delay and create its function which I can call whenever I want to trigger it. I have tried using millis() for small part of the delay code, but its not working. I am posting both the codes below.
Delay Code:
void setup() {
pinMode(A7, OUTPUT);
digitalWrite(A7, HIGH); //Turn on camera
delay(2100);
digitalWrite(A7, LOW);
delay(50);
digitalWrite(A7, HIGH); //Start Recording
delay(50);
digitalWrite(A7, LOW);
delay(6000); //Record video for 6 sec
digitalWrite(A7, HIGH); //Stop Recording
delay(50);
digitalWrite(A7, LOW);
}
void loop() {
}
Millis Code:
unsigned int milli2100, milli50, milli501;
void setup() {
pinMode(A7, OUTPUT);
camera(); //Function created to Trigger when set condition is met
}
void loop() {
}
void camera() {
digitalWrite(A7, HIGH);
if (millis() - milli2100 >= 2100) {
milli2100 += 2100;
digitalWrite(A7, LOW);
if (millis() - milli50 >= 50) {
milli50 += 50;
digitalWrite(A7, HIGH);
if (millis() - milli501 >= 50) {
milli501 += 50;
digitalWrite(A7, LOW);
}
}
}
}
Please explain why. It's going to take significant time and effort for you and us forum members to get your code and your level of understanding to the right level for that. So let's be sure there is a real need not to use delay() before we get into all that.
Yes, to turn on the camera, I need to keep A7 pin high for 2 sec. Also, I can't keep the camera on by default since it has 1 minute auto shutdown built in.
That isn't complete. I can tell just by looking at the first sketch. Please be more detailed and precise. Where did you get the delay values? If you have information resources, you should share them here.
The way I would do this with millis(), is to make a look up table of the delays, and also the pin states. Then I would index and increment through the table, feed the output of that to the delay logic.
1st Step:
Keep the A7 pin HIGH for 2.1 sec to power on the camera. After the 2.1s have passed, make the pin LOW and wait for 50ms before performing step2.
2nd Step:
Send a HIGH pulse of 50 ms to start recording i.e. Keep the pin HIGH for 50 ms and then make it LOW after the pin has been HIGH for 50ms which is similar to a button press.
There are many sensor datas like roll,pitch,yaw,pressure,altitude, latitude,longitude, etc which I need to send over radio, along with 2 PID controllers running simultaneously to maintain roll and pitch
/*
switch on/off one pin (?) in a sequence
https://forum.arduino.cc/t/guidance-for-implementation-of-millis/1105654/13
by noiasca
2023-03-23
to be deleted 2023-06
code in Forum
*/
const uint8_t pin = 13; // could be A7 on another microcontroller;
// not used any more - just as guide what's requested
void blocking() {
pinMode(A7, OUTPUT);
digitalWrite(A7, HIGH); //Turn on camera
delay(2100);
digitalWrite(A7, LOW);
delay(50);
digitalWrite(A7, HIGH); //Start Recording
delay(50);
digitalWrite(A7, LOW);
delay(6000); //Record video for 6 sec
digitalWrite(A7, HIGH); //Stop Recording
delay(50);
digitalWrite(A7, LOW);
}
// define the states of your sequence:
enum State {IDLE, ON_PULSE, ON, RECORDING_PULSE, RECORDING, STOP_PULSE, STOP};
static State state; // the current state of the sequence
uint32_t previousMillis = 0; // time management for the sequence
// start the sequence
void start() {
previousMillis = millis();
digitalWrite(pin, HIGH);
state = ON_PULSE;
}
// call the finite state machine and run through the states
void runFSM() {
uint32_t currentMillis = millis();
switch (state) {
case ON_PULSE :
if (currentMillis - previousMillis > 2100) {
previousMillis = currentMillis; // time management
Serial.println(F("end ON_PULSE")); // write to serial to keep track what's happening
digitalWrite(pin, LOW); // do something
state = ON; // next state
}
break;
case ON :
if (currentMillis - previousMillis > 50) {
previousMillis = currentMillis;
Serial.println(F("end ON"));
digitalWrite(pin, HIGH);
state = RECORDING_PULSE;
}
break;
case RECORDING_PULSE :
if (currentMillis - previousMillis > 50) {
previousMillis = currentMillis;
Serial.println(F("end RECORDING_PULSE"));
digitalWrite(pin, LOW);
state = RECORDING;
}
break;
case RECORDING :
if (currentMillis - previousMillis > 6000) {
previousMillis = currentMillis;
Serial.println(F("end RECORDING"));
digitalWrite(pin, HIGH);
state = STOP_PULSE;
}
break;
case STOP_PULSE :
if (currentMillis - previousMillis > 50) {
previousMillis = currentMillis;
Serial.println(F("end STOP_PULSE"));
digitalWrite(pin, LOW);
state = STOP;
}
break;
}
}
void setup() {
Serial.begin(115200);
pinMode(pin, OUTPUT);
start(); // start the sequence
}
void loop() {
runFSM(); // run the sequence
}
for sure it can be much less code. But this should show you how to implement a logic to do different things in a sequence. The concept is a "finite state machine" where each new step is triggered when the time has passed.
and I like drawings. For example the UML state machine
(imho the German article is better than the English one...)
p.s.:
I think it should be pretty clear, that you can use the "start()" more often.
Furthermore you can decide what should happen if you press "start()" when the sequence is already running. Easiest way would be if you just accept "start()" in IDLE and STOP.
Furthermore you can consider to just use IDLE or STOP (and omit the other state).
Again I think a nice drawing of a state diagram will make it obvious what you will need.
Ok then, I agree you have a valid reason to not use delay().
Many newcomers to the forum are convinced that they must not use delay(), otherwise the gods will strike them down or something, but have no actual reason not to use delay(), because their Arduino would be doing nothing else anyway.