Фототаймер для съемки таймлапса на Arduino.

Самодельный таймер для цейтраферной съемки, съемки time-lapse на arduino c OLED дисплеем, код из видео

 

timer_timelapse_oledПечатная плата в формате .lay

код проекта.

#include <OLED_I2C.h>
  
OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];

#define shotPin 3 // пин на затвор камеры   

#define keyDown 5 // кнопки
#define keyRight 6
#define keyUp 7
#define keyLeft 8

 
void setup(){
  pinMode(shotPin, OUTPUT); 
  pinMode(keyDown, INPUT_PULLUP);  
  pinMode(keyRight, INPUT_PULLUP);  
  pinMode(keyUp, INPUT_PULLUP);  
  pinMode(keyLeft, INPUT_PULLUP);  
  digitalWrite(shotPin, LOW);
  
  myOLED.begin();
  myOLED.setFont(SmallFont);
 
}
  

void menuTimeLap() { 
  unsigned int  delayTime = 2600;
  byte menuPos = 0; // позиция меню 
  unsigned int shot = 160;
  
  myOLED.clrScr();
  
  do { 
    delay(100);
    myOLED.clrScr();
    
      myOLED.print("Shoot:", LEFT, 0);  // количество кадров
      myOLED.printNumI(shot, 50, 0); 
      myOLED.print("frame", 80, 0);
      myOLED.print("Delay:", LEFT, 10);  // задержка        
      
        int lastnum = delayTime;
        byte a = lastnum / 10000;
 lastnum -= a * 10000;
 byte b = lastnum / 1000;
 lastnum -= b * 1000;
 byte c = lastnum / 100;    
       
         if (delayTime >= 10000) myOLED.printNumI(a, 44, 10); 
         else myOLED.print(" ", 45, 10);       
        myOLED.printNumI(b, 50, 10);
        myOLED.print(".", 56, 10);
        myOLED.printNumI(c, 61, 10);
        myOLED.print("sec", 85, 10);
   

        // длительность ролика
       myOLED.print("Video:", LEFT, 25);  
       myOLED.printNumF(shot/25, 1, 50, 25);   
       myOLED.print("sec", 80, 25); 
        
       // время сьемки
      myOLED.print("Time:~", LEFT, 35);
      float shot1 = shot;
      unsigned int time = ((delayTime*shot1)/1000)/60;
      myOLED.printNumF(time, 1, 50, 35);   
 
      myOLED.print("min", 80, 35);  
     
     myOLED.print("Start!", CENTER, 50); 
       
        /////  устанавливаем курсор согласно позиции.
      if (menuPos == 0) myOLED.print("<>", 115, 0);  
      else if (menuPos == 1) myOLED.print("<>", 115, 10);  
      else if (menuPos == 2) myOLED.print(">>", 115, 50);  
      
      ///// крутим позицию     
    if (!digitalRead(keyDown) && menuPos < 2) menuPos++;   
    else if (!digitalRead(keyUp) && menuPos != 0) menuPos--;  
       
      ///// крутим значение delayTime
    if (menuPos == 1 && !digitalRead(keyLeft)) { // delayTime и left 
      if (delayTime < 3500) delayTime -= 100;
      else if (delayTime < 5000) delayTime -= 200;
      else if (delayTime < 10000) delayTime -= 500;
      else delayTime -= 1000;
    } 
    else if (menuPos == 1 && !digitalRead(keyRight)) {  
      if (delayTime < 3500) delayTime += 100;
      else if (delayTime < 5000) delayTime += 200;
      else if (delayTime < 10000) delayTime += 500;
      else delayTime += 1000;
    } 
       ///// крутим значение shot
    if (menuPos == 0 && !digitalRead(keyRight)) shot += 10;   
    else if (menuPos == 0 && !digitalRead(keyLeft)) shot -= 10;   
    
    if (menuPos == 2 && !digitalRead(keyRight)) timeLap(delayTime, shot);   
 
  
    if (delayTime < 1900) delayTime = 30000;
    if (delayTime > 30000) delayTime = 1900;
    if (shot < 120) shot = 1500;
    if (shot > 1500) shot = 120;
    
    
    myOLED.update();     
  } while(1);  
}

 
void timeLap(unsigned int delayTime, unsigned int shot){
   unsigned long prMillis = 0;  
   float shotAll = shot; 
   myOLED.clrScr();
    
   do  {    
     if (millis() - prMillis > delayTime)  {  
       prMillis = millis();   
       shot--; 
   digitalWrite(shotPin, HIGH); // включаем  
   delay(200);
   digitalWrite(shotPin, LOW); // выключаем 
   
          
         myOLED.print("FrAll", LEFT, 0); 
         myOLED.printNumI(shotAll, 50, 0);
            
         float shot1 = shot;
         myOLED.print("Time:~", LEFT, 10);
         myOLED.printNumF(((delayTime*shot1)/1000)/60, 1, 50, 10);
         myOLED.print(" min", 80, 10);
         
         // показываем проценты
         myOLED.setFont(MediumNumbers);
         myOLED.printNumF(shot/shotAll*100, 1, 25, 40);
         myOLED.setFont(SmallFont);
         myOLED.print(" %", 75, 40);
  
         myOLED.printNumI(shotAll-shot, 20, 25);        
         myOLED.print(" << ", 40, 25);      
         myOLED.printNumI(shot, 70, 25);         
    
   myOLED.update(); 
   myOLED.clrScr();   
  }

         ///// крутим значение shot
    if (!digitalRead(keyDown)){
      shotAll += 10;      
      shot += 10;   
      delay(150);
    }
 
    
  
 } while (shot != 0);
 
  myOLED.clrScr();
}
///////
 
void loop(){
 

   menuTimeLap();

}