Stuck on how to code an intervelometer

bu chance, how would i go about using a nexus display to make an intervelometer (a device that can set a camera to take photoes at a set interval, with a set number of photoes and with a set exposure)

#define SHUTTER_PIN 2 // The pin that connects to the shutter of the camera. Must be kept HIGH if shutter is not to be triggered
//#define FOCUS_PIN 3 // The pin that connects to the shutter of the camera. Must be kept HIGH if shutter is not to be triggered
#define SHUTTER_TRIGGER 250

#include <SoftwareSerial.h>
SoftwareSerial btSerial(4,3); // RX, TX

void setup() {
  btSerial.begin(115200); // start serial peripheral

  pinMode(SHUTTER_PIN,OUTPUT);
  //pinMode(FOCUS_PIN,OUTPUT);
  
  digitalWrite(SHUTTER_PIN,HIGH);
  //digitalWrite(FOCUS_PIN,HIGH);
}

unsigned long interval = 0;
unsigned long numberOfPhotos = 0;
unsigned long cameraExposure = 0;
String action = "";
bool messageComplete = false;  

void loop() {
  if(btSerial.available()) // If there is serial data waiting in the buffer
  {
    char actionChar = btSerial.read();
    if(actionChar == '\n') {
      messageComplete = true;
      //Serial.print(action);
    }
    else {
      action += actionChar;
    }
  }
  if(messageComplete) {
    
    String key = action.substring(0, action.indexOf(" "));
    String value = action.substring(action.indexOf(" ") + 1);
  
    if(key == "setNumberOfPhotos") {
        numberOfPhotos = value.toInt();
    }
    else if(key == "setInterval") {
        interval = value.toInt() * 1000;
    }
    else if(key == "setCameraExposure") {
        cameraExposure = value.toInt() * 1000;
    }
    else if(key == "start") {
      btSerial.println("Starting time lapse: ");
      unsigned long remainingPhotos = numberOfPhotos;
      while(remainingPhotos) {
        //Serial.print("Taking photo number "); Serial.print(remainingPhotos);
        digitalWrite(SHUTTER_PIN,LOW);
        delay(SHUTTER_TRIGGER);
        digitalWrite(SHUTTER_PIN,HIGH);
        delay(interval - cameraExposure - SHUTTER_TRIGGER);
        remainingPhotos --;
      }     
    }
    else {
      btSerial.println("Action not recognized");
    }
    btSerial.println("////////////////////////////////////////////");
    btSerial.print("Photos: "); btSerial.print(numberOfPhotos); btSerial.print(". Interval: "); btSerial.print((float)interval/1000); btSerial.print(" seconds. "); btSerial.print("Exposure: "); btSerial.print((float)cameraExposure/1000); btSerial.println(" seconds");
    btSerial.print("It will take "); btSerial.print((float)interval * numberOfPhotos / 1000); btSerial.println(" seconds to complete this timelapse");
    btSerial.print("Played back at 30fps the resulting clip will be "); btSerial.print((float)numberOfPhotos/30); btSerial.println(" seconds long");
    btSerial.println("////////////////////////////////////////////");
    action = "";
    messageComplete = false; 
  }
}

i want to intergrate the intervelometer code from this ide but alas, i dont have much coding knowladge especially in nexus displays (if not any)
this is what ive tried to do but it just doesnt seem to work. like the values wont print onto t3 and im just kinda stumped

#include <Nextion.h>

#define LED_PIN 2
#define LED_TRIGGER 250

int variable1 = 0;
int variable2 = 0;
int counter = 0;
int CurrentPage = 0; 

NexButton bSta = NexButton(0, 13, "bSta");
NexButton bPhN = NexButton(0, 18, "bPhN");
NexButton bInt = NexButton(0, 19, "bInt");
NexButton bExp = NexButton(0, 20, "bExp");
NexNumber nPhN = NexNumber(0, 3, "nPhN"); 
NexNumber nInt = NexNumber(0, 5, "nInt");
NexNumber nExp = NexNumber(0, 7, "nExp");
NexText t3 = NexText(0, 8, "t3");
NexSlider hPhN = NexSlider(0, 10, "hPhN");
NexSlider hInt = NexSlider(0, 11, "hInt");
NexSlider hExp = NexSlider(0, 12, "hExp");
NexSlider hBri = NexSlider(1, 3, "hBri");
NexProgressBar jProg1 = NexProgressBar(0, 9, "jProg1");
NexProgressBar jProg2 = NexProgressBar(1, 2, "jProg2");

char buffer[100] = {0};

NexTouch *nex_listen_list[] = 
{
  &bSta,
  &bPhN,
  &bInt,
  &bExp,
  &hPhN,
  &hInt,
  &hExp,
  &hBri, 
  NULL
};

unsigned long interval = 0;
unsigned long numberOfPhotos = 0;
unsigned long cameraExposure = 0;
String action = "";
bool messageComplete = false;



void hPhNPopCallBack(void *ptr){
  uint32_t number1 = 0;
  hPhN.getValue(&number1);

  if(number1==0){
    hPhN.getValue(&number1);
  }
  if(number1==0){
    hPhN.getValue(&number1);
  }
  if(number1==0){
    hPhN.getValue(&number1);
  }
  if(number1==0){
    hPhN.getValue(&number1);
  }
  if(number1==0){
    hPhN.getValue(&number1);
  }
  if(number1==0){
    hPhN.getValue(&number1);
  }
  if(number1==0){
    hPhN.getValue(&number1);
  }
  if(number1==0){
    hPhN.getValue(&number1);
  }
  if(number1==0){
    hPhN.getValue(&number1);
  }
    
  Serial.print("nPhN.val=");
  Serial.print(number1);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
   
}

void hIntPopCallBack(void *ptr){
  uint32_t number2 = 0;
  hInt.getValue(&number2);

  if(number2==0){
    hInt.getValue(&number2);
  }
  if(number2==0){
    hInt.getValue(&number2);
  }
  if(number2==0){
    hInt.getValue(&number2);
  }
  if(number2==0){
    hInt.getValue(&number2);
  }
  if(number2==0){
    hInt.getValue(&number2);
  }
  if(number2==0){
    hInt.getValue(&number2);
  }
  if(number2==0){
    hInt.getValue(&number2);
  }
  if(number2==0){
    hInt.getValue(&number2);
  }
  if(number2==0){
    hInt.getValue(&number2);
  }
    
  Serial.print("nInt.val=");
  Serial.print(number2);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
   
}

void hExpPopCallBack(void *ptr){
  uint32_t number3 = 0;
  hExp.getValue(&number3);

  if(number3==0){
    hExp.getValue(&number3);
  }
  if(number3==0){
    hExp.getValue(&number3);
  }
  if(number3==0){
    hExp.getValue(&number3);
  }
  if(number3==0){
    hExp.getValue(&number3);
  }
  if(number3==0){
    hExp.getValue(&number3);
  }
  if(number3==0){
    hExp.getValue(&number3);
  }
  if(number3==0){
    hExp.getValue(&number3);
  }
  if(number3==0){
    hExp.getValue(&number3);
  }
  if(number3==0){
    hExp.getValue(&number3);
  }
    
  Serial.print("nExp.val=");
  Serial.print(number3);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
   
}

void bPhNPopCallBack(void *ptr)
{
  
}

void bIntPopCallBack(void *ptr)
{
  
}

void bExpPopCallBack(void *ptr)
{
  
}

void bStaPushCallBack(void *ptr)
{
  
}


void setup() {  // put your setup code here, to run once:

  Serial.begin(9600);

  // I am going to change the Serial baud to a faster rate (optional):
  delay(500);  // This dalay is just in case the nextion display didn't start yet, to be sure it will receive the following command.
  Serial.print("baud=115200"); 
  Serial.write(0xff);  
  Serial.write(0xff);
  Serial.write(0xff);

  Serial.end();  // End the serial comunication of baud=9600.

  Serial.begin(115200);  // Start serial comunication at baud=38400.


  bSta.attachPush(bStaPushCallBack);
  //hPhN.attachPop(hPhNPopCallBack);
  //hInt.attachPop(hIntPopCallBack);
  //hExp.attachPop(hExpPopCallBack);
  //hBri.attachPop(hBriPopCallBack);

  
  pinMode(LED_PIN, OUTPUT);

  digitalWrite(LED_PIN, HIGH);
}
  

void loop() 
{
  nexLoop(nex_listen_list);  
}

i guess the idea is to change the slider to the set value suck as 2000 photos and than press the cutton next to said slider. this will print the text onto t3 from the lower part of the first code i have uploaded aswell as set the camera shutter to go off 2000 times. this is the same for the exposure and interval exept when those are printed it will calculate the total time.

sorry if this is allot i just have no idea what im doing wrong and just quite stumped.

The Nextion display is capable of doing this on its own it has GPIO outputs and timer functions but you have to learn how to write the code on the display just as I did. I now have a display remote controlling and displaying the state of my off grid solar system directly with no micro controller in between. I previously had only written in software for AVR micro controller in basic. The code would be simpler than what you have shown. You need to provide the details of the connections to the camera so people can help.

what i am using to connect to the camera is just a small 2.3mm jack that actvates the shutter by opening and closing. so basically when i set the exposure and all that itll close that connction for lets say 10 seconds, wait 5 and close it for another 10.
so the camera isnt directly being controlled, the arduino is basically blinking an led with the interval that i have given it.
if this doesnt make sence im sorry about that lmao. dont know all the terms properly.

so really the full idea is to change the slider values, press the button next to them and this will print onto t3 the e number of photoes, exposure, interval and calculate the total time it will take. than press start timelapse, send all that data to the led for example and that will than blink 10 times, for 10 seconds every 20 seconds as such.
so in im able to do that without an arduino that would be great but im pretty sure the arduino is needed.

after a whole day of trying to figure this out i think i finally get what you mean. the original code was used with a bluetooth chip and an app that sends data from a text box etc suck as “setNumberOfPhotos”, “setInterval” and “setExposure” and that would process through the arduino and print it onto a serial moniter on the app. so as your explained, if i code the nextion display to do the exact same thing the app did i wont have to change the code at all exept for some few minor tweeks.
if this is the case do you have any recomendations to places i should go to learn hw to code directly in the nextion editor?
thanks.

Its simpler than arduino but similar as you have timer objects.
You need to read the nextion instruction-set

I would use an opto coupler connected to the GPIO to run the shutter and getting the GPIO expansion board gives you buttons , buzzer and an easy way to connect to the port .
Search google for using the GPIO for examples.
Start now with getting the sliders to change timer values and a button to enable (start) the timers do it one set nextion object at a time so one slider one timer and a button this is how I started until I learnt how to use each object. I will try to post some code for this soon not time at the moment testing batteries.

thanks allot.
will look through this in the morning

EDIT: i have gotten all the sliders to work and print all the values that are necisarry. the final problem is to have averything print onto the text box

it isnt much but i have currently gotten the display to print commands on the button presses to than be read by the arduino which in such prints on the serial moniter the text that calculate the times and such. i then went onto figure out the start timelapse button which i did ontergrade the same cose from the intervelometer sketch that turns the led off and on (simulating the camera shutter) and that also works now.
my main issue i am currently having is reading the slider values and printing thise to the arduino because currenty i have manually set the number of photos, interval and exposure myself for the whole testing stuff so if you have any neet tricks that i may benefit from i would greatly appretiate it.

//#include <SoftwareSerial.h>
//SoftwareSerial nextion(12, 13);

#define SHUTTER_PIN 2
#define SHUTTER_TRIGGER 2

int i = 0;

void setup() 
{
  Serial.begin(9600);
  Serial.println("HELLO");

  pinMode(SHUTTER_PIN,OUTPUT);

  digitalWrite(SHUTTER_PIN,HIGH);
}


unsigned long numberOfPhotos = 5;
unsigned long interval = 5;
unsigned long cameraExposure = 2;
String action = "";
bool messageComplete = false;


void loop() 
{
  if(Serial.available())
  {
    char character="";
    String data_from_display="";
    delay(30);
    while(Serial.available()){
      character = char(Serial.read());
      data_from_display += character;
    }
    Serial.println(data_from_display);
    sendData(data_from_display);
  }
}

void sendData(String data_from_display)
{
  if(data_from_display == "setNumberOfPhotos"){
    numberOfPhotos = Serial.read();
    
    Serial.println("////////////////////////////////////////////");
    Serial.print("Photos: "); Serial.print(numberOfPhotos); Serial.print(". Interval: "); Serial.print((float)interval/1000); Serial.print(" seconds. "); Serial.print("Exposure: "); Serial.print((float)cameraExposure/1000); Serial.println(" seconds");
    Serial.print("It will take "); Serial.print((float)interval * numberOfPhotos / 1000); Serial.println(" seconds to complete this timelapse");
    Serial.print("Played back at 30fps the resulting clip will be "); Serial.print((float)numberOfPhotos/30); Serial.println(" seconds long");
    Serial.println("////////////////////////////////////////////");
    action = "";
    messageComplete = false;
  }
  if(data_from_display == "setInterval"){ 
    interval = 5 * 1000;
    
    Serial.println("////////////////////////////////////////////");
    Serial.print("Photos: "); Serial.print(numberOfPhotos); Serial.print(". Interval: "); Serial.print((float)interval/1000); Serial.print(" seconds. "); Serial.print("Exposure: "); Serial.print((float)cameraExposure/1000); Serial.println(" seconds");
    Serial.print("It will take "); Serial.print((float)interval * numberOfPhotos / 1000); Serial.println(" seconds to complete this timelapse");
    Serial.print("Played back at 30fps the resulting clip will be "); Serial.print((float)numberOfPhotos/30); Serial.println(" seconds long");
    Serial.println("////////////////////////////////////////////");
    action = "";
    messageComplete = false;
  }
  if(data_from_display == "setExposure"){ 
    cameraExposure = 2 * 1000;
    
    Serial.println("////////////////////////////////////////////");
    Serial.print("Photos: "); Serial.print(numberOfPhotos); Serial.print(". Interval: "); Serial.print((float)interval/1000); Serial.print(" seconds. "); Serial.print("Exposure: "); Serial.print((float)cameraExposure/1000); Serial.println(" seconds");
    Serial.print("It will take "); Serial.print((float)interval * numberOfPhotos / 1000); Serial.println(" seconds to complete this timelapse");
    Serial.print("Played back at 30fps the resulting clip will be "); Serial.print((float)numberOfPhotos/30); Serial.println(" seconds long");
    Serial.println("////////////////////////////////////////////");
    action = "";
    messageComplete = false;
  }
  if(data_from_display == "start"){
    Serial.println("Starting time lapse: ");
      unsigned long remainingPhotos = numberOfPhotos;
      while(remainingPhotos) {
        Serial.print(remainingPhotos );       
        digitalWrite(SHUTTER_PIN,LOW);
        delay(cameraExposure + SHUTTER_TRIGGER);
        digitalWrite(SHUTTER_PIN,HIGH);
        delay(interval - cameraExposure);
        remainingPhotos --;     
    }
  }
}

void endNextionCommand()
{
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}

//jProg1=hPhN-remainingPhotos

with the “if(data_from_display == “setNumberOfPhotos”){ numberOfPhotos = Serial.read();” i was teating that and i have a delay on the nestion editer that prints “setNumberOfPhotos” waits 250 ms than prints numberOfPhotos.txt (my variable relating to photo number). when i have a delay in the arduino code inbetween the if statment and the numbofphotoes = serial read it either came out as 4294967295 number of photos at a delay of 250 or less and 40-50+ aswell as cuts the furst didget off the number if the slider is 4 didgets with a delay of 250 or more.
so im unsure.

sorry about my writing being basically unreadable lmao. when i talk about an issue im having and trying to explain it i just loose all memory of grammer

On a new project in the editor create a slider , two text box and a button also create a timer and a variable
text box two t1 set txt_maxl to 20
set the timer enabled en to 0 this disables the timer
in the slider touch move event put
covx h0.val,t0.txt,0,0 //converts a number to text

in the button touch press event
t1.txt=“timer started”
va0.val=h0.val
va0.val*=1000 //timer is in milliseconds *=1000 multiplies by 1000
tm0.tim=va0.val
tm0.en=1

in the timer event put
t1.txt=“click”
tm0.en=0
run debug and watch
The timer will run for the number of seconds entered by the slider

regards paul

thanks,

but do you think itll be possible to use the void loop code that reads the serial to collect the data sent from nextion and converts it into a string (ref 1) and sends that to the void sendData loop, or atleast some iteration of it to convert the line of code that prints the values set from the slider (ref 2) to its own string and sends it to another void sendData thing so i can both cut down the size of the code and should be able to print the text onto the nextion text feild

ref 1

void loop() 
{
  if(Serial.available())
  {
    char character = "";
    String data_from_display="";
    delay(30);
    while(Serial.available()){
      character = char(Serial.read());
      data_from_display += character;
    }
    Serial.println(data_from_display);
    sendData(data_from_display);
  }
}

ref 2

void sendData(String data_from_display)
{
  if(data_from_display.substring(0,3) == "PHN"){
    numberOfPhotos = data_from_display.substring(3,7).toInt();
    
    Serial.println("////////////////////////////////////////////");
    Serial.print("Photos: "); Serial.print(numberOfPhotos); Serial.print(". Interval: "); Serial.print((float)interval/1000); Serial.print(" seconds. "); Serial.print("Exposure: "); Serial.print((float)cameraExposure/1000); Serial.println(" seconds");
    Serial.print("It will take "); Serial.print((float)interval * numberOfPhotos / 1000); Serial.println(" seconds to complete this timelapse");
    Serial.print("Played back at 30fps the resulting clip will be "); Serial.print((float)numberOfPhotos/30); Serial.println(" seconds long");
    Serial.println("////////////////////////////////////////////");
    action = "";
    messageComplete = false;

The code I posted prints the value of the slider to the text field no need of the arduino the nextion does it. covx h0.val,t0.txt,0,0 //converts a number to text and puts it into the text t0 box

yes, but the text i want to be printed is
////////////////////////////////////////////
Photos: 21. Interval: 4.00 seconds. Exposure: 1.00 seconds
It will take 84.00 seconds to complete this timelapse
Played back at 30fps the resulting clip will be 0.70 seconds long
////////////////////////////////////////////
with whatever values i set and also “starting timelapse:” and the photo number that is being taken.
so i have more detail insead of 1 single value

the nextion can do that if set photo numb is 21 and set interval is 4 then in your picture
if you create a number variable (they are number by default)

va1.val=t0.val //first set the variable to slider one value
va1.val*=t2.val //multiply by slider two value

so 21 * 4 = 84

so how would i go about it setting the text box to be the specific text i sent above? i can kinda see how i can get the values to begin with and how i should be able to intergrate them with something like “Photos: t0.val. Interval: t2.val seconds. Exposure: t1.val seconds” etc
but if i am correct you arnt neciserily able to plug the vlues in like this. and also adds the problem of printing different things. when you set the photo number itll print all that but the exposure and int are = 0, than set the interval and it prints the same withthe added variable, same goes for exposre and on press of “start” itll print ‘Starting timelapse:’ and tham print the photo number which will be another variable that can be set by something as simple as va2.val=t1.val, va2.val–

So to fill a text box
we create a text variable va2
t3.txt=“Photos: "
covx h0.val,va2.txt,0,0
t3.txt+=va2.txt
t3.txt+=” Interval: "
covx h1.val,va2.txt,0,0
t3.txt+=va2.txt
t3.txt+=" seconds. Exposure: "
covx h3.val,va2.txt,0,0
t3.txt+=va2.txt
t3.txt+=" seconds. "
and so on

so how will i set the text to be this on a specific button press?

also is there any way i can get the progress bar to keep up with the actuall progress? in my testing i cant get the progress bar ro start from 0 and increese to 100 evenly due to the nature of the number of photos. is there a way to print a persentage of 100 to the progress bar?

That code goes in the Touch Press Event of the button
With the intervals you use timer so set a timer to run every 4 seconds tim.val=4000 set another time for 1 second tim.val=1000 the press event in a button enables 4 second timer when it then enables 1 second timer and disables itself the 1 second timer enables 4 second timer runs a loop , in ne of the timers you decrement a variable starting at 21 (in your example) and when it gets to zero you disable timers.
Going to dinner back after

i dont think i get this which is fine because i can just remove the progress bar but in the text box, how do we add text to be on multiple lines?

Multi line text (had find out myself)
this prints 3 lines \r is the device
t2.txt=“Line 1 \r Line 2 \r Line 3”
then line 4
t2.txt+=“\r Line4”

Now the progress bar is a bit of a problem as you would need to divide 100 by the 21 and then increment it by that value each time the photo number increases but it only takes whole numbers so 21 gives 4.7… so some maths would need to be done to round up/down why not a text box counting down.
Hope this is helping you.

i have a text box counting down but that is being dont in t3 aswell as the other stuff o it does make sence to just have a seperate text bow for that. im thinking of having 2 displays, one with the sliders and the other with the text boxes but this is a problem for me to figure out when ive finished the rest.

i also still cant figure out how to print this exact text onto the text box.
/
////////////////////////////////////////////
Photos: 0. Interval: 0.00 seconds. Exposure: 0.00 seconds
It will take 0.00 seconds to complete this timelapse
Played back at 30fps the resulting clip will be 0.00 seconds long
////////////////////////////////////////////
because when i try it doent print the ///// and i still cant figure out the other lines

and yes your helping quite allot and i appretiate your patiance :slight_smile: