Timer Programming on Arduino

 

ul millis() Returns the number of milliseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.
ul micros() Returns the number of microseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 70 minutes. On 16 MHz Arduino boards (e.g. Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is always a multiple of four). On 8 MHz Arduino boards (e.g. the LilyPad), this function has a resolution of eight microseconds
delay(ul ms) Pauses the program for the amount of time (in milliseconds) specified as parameter
delayMicroseconds(ui us) Pauses the program for the amount of time (in microseconds) specified as parameter. There are a thousand microseconds in a millisecond, and a million microseconds in a second.

Currently, the largest value that will produce an accurate delay is 16383. This could change in future Arduino releases. For delays longer than a few thousand microseconds, you should use delay() instead

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    ledState = !ledState;

    // set the LED with the ledState of the variable:
    digitalWrite(LED_BUILTIN, ledState);
  }
}

Programing Flow of Cenz

#define led_pin 13

void setup() {
  // put your setup code here, to run once:
  pinMode(led_pin, OUTPUT);
}

void loop() {
  //variable declaration
  unsigned long current_millis = millis();
  static unsigned long led_previous_millis = 0;
  static bool led_toggle_flag = false;


  //=========checkFlag()======
  if(current_millis - led_previous_millis >= 1000){
    //toggle LED function flag on
    led_toggle_flag = true;
  }

  //===========do()===========
  if(led_toggle_flag){
    led_toggle(led_pin);
    
    //reset the flag and timer
    led_toggle_flag = false;
    led_previous_millis = current_millis;
  }
}

void led_toggle(unsigned char pin){
  digitalWrite(pin, !digitalRead(pin));
}
#define led_pin 13

typedef struct EventRegister{
  unsigned long previous_millis;
  bool check_flag;
  unsigned long duration;
};

EventRegister ledToggle{0, false, 1000};

void setup() {
  // put your setup code here, to run once:
  pinMode(led_pin, OUTPUT);
}

void loop() {
  //variable declaration
  unsigned long current_millis = millis();

  //=========checkFlag()======
  if(current_millis - ledToggle.previous_millis >= ledToggle.duration){
    //toggle LED function flag on
    ledToggle.check_flag = true;
  }

  //===========do()===========
  if(ledToggle.check_flag){
    led_toggle(led_pin);
    //reset the flag and timer
    ledToggle.check_flag = false;
    ledToggle.previous_millis = current_millis;
  }
}

void led_toggle(unsigned char pin){
  digitalWrite(pin, !digitalRead(pin));
}

Ref:
https://www.arduino.cc/reference/en/language/functions/time/millis/
https://www.arduino.cc/reference/en/language/functions/time/micros/
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

Advertisements

Arduino SPI

https://www.microchip.com/wwwproducts/en/ATmega328p
https://www.arduino.cc/en/Reference/SPI

The Arduino Lib is for SPI Master, if you would like to play with SLAVE >> 0) –> to enable SPI module

https://github.com/PaulStoffregen/SPI/blob/master/SPI.h

//master loopback
#include 

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  SPI.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  
}

void serialEvent(){
//statements
      Serial.print(SPI.transfer(Serial.read()));
}

//unfinished

#define pinIsSlave 2
#define pinNSS 10
//pin2 is High --> Slave
//pin2 is Low  --> Master

#define DDR_SPI DDRB
#define DD_MOSI DDB3
#define DD_MISO DDB4
#define DD_SCK  DDB5
#define DD_NSS  DDB2

//==========
//pin   Master    Slave
//MOSI  User      INPUT
//MISO  INPUT     User
//SCK   User      INPUT
//NSS   User      INPUT

//__enable_interrupt();
void SPI_MasterInit(void);
char SPI_MasterTransmit(char cData);
void SPI_SlaveInit(void);
char SPI_SlaveReceive(void);

void setup() {
  pinMode(pinIsSlave, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Master/Slave SPI - USART Firmware V1.0");
  Serial.println("pin2 is High --> Slave || pin2 is Low  --> Master");
  
  //Program Start
  if(digitalRead(pinIsSlave)){
   //========================= SLAVE ===================
   Serial.println("\n\n====Slave Mode is Selected====");
   SPI_SlaveInit();
  }else{
   //========================= MASTER ==================
   Serial.println("\n\n====Master Mode is Selected====");
   pinMode(pinNSS, OUTPUT);
   SPI_MasterInit();

   char a = SPI_MasterTransmit('i');
   Serial.print(a);

  }
}

void SPI_MasterInit(void){
  // Set MOSI and SCK output, all others untouch
  PORTB = 0xFF;
  DDR_SPI = (1 << DD_MOSI)|(1 << DD_SCK);

  //Enable SPI, Master,
  SPCR = (1 << SPE)|(1 << MSTR);

  //SPI0 Clock Rate Select to f_osc/16
  SPCR |= (1 << SPR0);
}

char SPI_MasterTransmit(char cData){
  //Start Transmission
  SPDR = cData;

  //wait until Commication complete
  while(!(SPSR & (1 << SPIF)));

  return SPDR;
//
//    SPDR = cData;
//    asm volatile("nop");
//    while (!(SPSR & _BV(SPIF))) ; // wait
//    return SPDR;

}

void SPI_SlaveInit(void){
  //Set MISO output, all other untouch
  DDR_SPI = (1 << DD_MISO);

  //Enable SPI
  SPCR = (1 << SPE);  
}

char SPI_SlaveReceive(void){
  //wait until Commication complete
  while(!(SPSR & (1 << SPIF)));

  //Start Transmission
  return SPDR;
}










void loop() {
  // put your main code here, to run repeatedly:

}


ref:
http://www.gammon.com.au/forum/?id=10892&reply=1#reply1