Return to ES100/Arduino Instructions
// Program WWVB_ES100_Test.ino////------------------------------------------------------------------------------//------------------------------------------------------------------------------// THIS CODE INCLUDES AMENDMENTS FOR TESTING// by Keith Greiner 2019_03_08// As with the original program (sketch)/ the program, as amended, is provided// no express or implied warranty whatsoever. //// es100_host_arduino.c//// Xtendwave ES100 Example Host MCU Code for Arduino - version 0002//// Copyright 2013 Xtendwave//// THIS SOFTWARE IS PROVIDED TO YOU "AS IS," AND WE MAKE NO EXPRESS OR IMPLIED// WARRANTIES WHATSOEVER WITH RESPECT TO ITS FUNCTIONALITY, OPERABILITY, OR USE,// INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE, OR INFRINGEMENT. WE EXPRESSLY DISCLAIM ANY// LIABILITY WHATSOEVER FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR// SPECIAL DAMAGES, REGARDLESS OF THE FORM OF ACTION OR LEGAL THEORY UNDER// WHICH THE LIABILITY MAY BE ASSERTED, EVEN IF ADVISED OF THE POSSIBILITY OR// LIKELIHOOD OF SUCH DAMAGES.//// This software contains example C code that shows how an Arduino host// microcontroller can control an ES100 device. The software uses the// Serial.print() function to display the time.//// 4 pins are used. //// Arduino Uno (Problem with voltages, do not use without adaptation)// 1 digital output pin controls EN (ES100 Pin 5, Arduino Uno Digital Pin 4) and // 1 digital input pin monitors IRQ (ES100 Pin 2, Arduino Uno Digital Pin 2) . // Arduino Due// 1 digital output pin controls EN (ES100 Pin 5, Arduino Uno Digital Pin 22) and // 1 digital input pin monitors IRQ (ES100 Pin 2, Arduino Uno Digital Pin 24) . //// Two pins, SCL and SDA, connect to the ES100 serial interface.//// Arduino Uno pins (problem with voltages, do not use without adaptation)// ES100 SCL = pin 4 to Arduino Uno SCL = Analog pin 4 or top right 2// ES100 SDA = pin 3 to Arduino Uno SDA = Analog pin 5 or top right 1// Arduino Due // ES100 SCL = pin 4 to Arduino Due SCL = Analog pin 21 // ES100 SDA = pin 3 to Arduino Due SDA = Analog pin 20 //// This software was testing using Arduino Software version 1.5.2 and an Arduino Due.//// User-Supplied Functions//// mcu_init// mcu_gpio_set_high// mcu_gpio_set_low// mcu_gpio_read// mcu_timer_read// mcu_timer_wait_us//// General I2C Functions//// i2c_write// i2c_read//// ES100 Functions//// es100_write_register// es100_read_register// es100_enable// es100_disable// es100_start_rx// es100_wait_for_irq// es100_get_irq_status// es100_read_time//// Other//// setup// loop////#include <Time.h>#include <TimeLib.h>float decimalMinutes = 0;//------------------------------------------------------------------------------//------------------------------------------------------------------------------#include <Wire.h>//------------------------------------------------------------------------------// MCU constants - USER TO MODIFY//------------------------------------------------------------------------------// GPIO pins#define GPIO_EN 22 #define GPIO_IRQ 24 //------------------------------------------------------------------------------// constants//------------------------------------------------------------------------------// Code from Blink.ino// Pin 13 has an LED connected on most Arduino boards.// give it a name:int led = 13;// End code from Blink.inoint beginTime = 0;int endTime = 0;int elapsedTime = 0;double Elapsed_Time_in_Minutes = 0; // my variable kg// I2C slave address#define ES100_SLAVE_ADDR 0x32// enable delay time//#define ENABLE_DELAY_US 1500// Below changed 2018_12_07#define ENABLE_DELAY_US 1000000 // 100ms: module version 1 only// I2C clock high/low time#define SCL_TIME_US 2// ES100 API register addresses#define ES100_CONTROL0_REG 0x00#define ES100_CONTROL1_REG 0x01#define ES100_IRQ_STATUS_REG 0x02#define ES100_STATUS0_REG 0x03#define ES100_YEAR_REG 0x04#define ES100_MONTH_REG 0x05#define ES100_DAY_REG 0x06#define ES100_HOUR_REG 0x07#define ES100_MINUTE_REG 0x08#define ES100_SECOND_REG 0x09#define ES100_NEXT_DST_MONTH_REG 0x0A#define ES100_NEXT_DST_DAY_REG 0x0B#define ES100_NEXT_DST_HOUR_REG 0x0C//------------------------------------------------------------------------------// array to store date and time//------------------------------------------------------------------------------#define DT_STATUS 0#define DT_YEAR 1#define DT_MONTH 2#define DT_DAY 3#define DT_HOUR 4#define DT_MINUTE 5#define DT_SECOND 6#define DT_NEXT_DST_MONTH 7#define DT_NEXT_DST_DAY 8#define DT_NEXT_DST_HOUR 9#define DT_LENGTH 10//------------------------------------------------------------------------------// mcu functions - USER TO MODIFY//------------------------------------------------------------------------------void mcu_init(void){ // optional code to initialize GPIO, timer and other MCU functions pinMode(GPIO_EN, OUTPUT); pinMode(GPIO_IRQ, INPUT); Wire.begin(); Serial.begin(9600);}void mcu_gpio_set_high(int pin){ // set pin to a logic one digitalWrite(pin, HIGH);}void mcu_gpio_set_low(int pin){ // set pin to a logic zero digitalWrite(pin, LOW);}int mcu_gpio_read(int pin){ // read current state of input pin return(digitalRead(pin));}int mcu_timer_read(void){ // read timer value and return as integer return(millis());}void mcu_timer_wait_us(int count){ // wait 1 microsecond or greater for each count delayMicroseconds(count);}//------------------------------------------------------------------------------// write I2C data - USER TO MODIFY//------------------------------------------------------------------------------void i2c_write(uint8_t slave_addr, uint8_t num_bytes, uint8_t *ptr){ int i; Wire.beginTransmission(slave_addr); for (i=0; i<num_bytes; i++) { Wire.write(ptr[i]); } Wire.endTransmission();}//------------------------------------------------------------------------------// read I2C data - USER TO MODIFY//------------------------------------------------------------------------------void i2c_read(uint8_t slave_addr, uint8_t num_bytes, uint8_t *ptr){ int i; const uint8_t stop_flag = 1; Wire.requestFrom(slave_addr, num_bytes, stop_flag); Serial.print("Reading in i2c_read(...) function. " ); // My addition for test Serial.print(num_bytes); Serial.print(" "); Serial.print(Wire.available()); Serial.print("\n"); for(i=0; (i<num_bytes && Wire.available()); i++) { ptr[i] = Wire.read(); }}//------------------------------------------------------------------------------// write data to an ES100 API register//------------------------------------------------------------------------------void es100_write_register(uint8_t addr, uint8_t data){ uint8_t es100_write_array[2]; es100_write_array[0]= addr; es100_write_array[1]= data; i2c_write(ES100_SLAVE_ADDR, 0x2, es100_write_array);}//------------------------------------------------------------------------------// read data from an ES100 API register//------------------------------------------------------------------------------uint8_t es100_read_register(uint8_t addr){ uint8_t data; i2c_write(ES100_SLAVE_ADDR, 0x1, &addr); i2c_read(ES100_SLAVE_ADDR, 0x1, &data); return(data);}//------------------------------------------------------------------------------// enable ES100//------------------------------------------------------------------------------void es100_enable(void){ mcu_gpio_set_high(GPIO_EN);}//------------------------------------------------------------------------------// disable ES100//------------------------------------------------------------------------------void es100_disable(void){ mcu_gpio_set_low(GPIO_EN);}//------------------------------------------------------------------------------// start reception//------------------------------------------------------------------------------void es100_start_rx(){ es100_write_register(ES100_CONTROL0_REG, 0x01); // perform read of control register for i2c debug only es100_read_register(ES100_CONTROL0_REG);}//------------------------------------------------------------------------------// wait for falling edge of IRQ//------------------------------------------------------------------------------void es100_wait_for_irq(){ Serial.print("\nInside es100_wait_for_irq()\n"); //Serial.print("Time since start "); //Serial.print(millis()); //Serial.print("\n"); while(mcu_gpio_read(GPIO_IRQ)); // wait until IRQ is low //contents of mcu_gpio_read are ---> return(digitalRead(pin));}//------------------------------------------------------------------------------// read IRQ status register//------------------------------------------------------------------------------uint8_t es100_get_irq_status(){ //Read IRQ status register return(es100_read_register(ES100_IRQ_STATUS_REG));}//------------------------------------------------------------------------------// read date and time from API registers//------------------------------------------------------------------------------void es100_read_time(int dt_array[]){ dt_array[DT_STATUS] = es100_read_register(ES100_STATUS0_REG); dt_array[DT_YEAR] = es100_read_register(ES100_YEAR_REG); dt_array[DT_MONTH] = es100_read_register(ES100_MONTH_REG); dt_array[DT_DAY] = es100_read_register(ES100_DAY_REG); dt_array[DT_HOUR] = es100_read_register(ES100_HOUR_REG); dt_array[DT_MINUTE] = es100_read_register(ES100_MINUTE_REG); dt_array[DT_SECOND] = es100_read_register(ES100_SECOND_REG); dt_array[DT_NEXT_DST_MONTH] = es100_read_register(ES100_NEXT_DST_MONTH_REG); dt_array[DT_NEXT_DST_DAY] = es100_read_register(ES100_NEXT_DST_DAY_REG); dt_array[DT_NEXT_DST_HOUR] = es100_read_register(ES100_NEXT_DST_HOUR_REG);}//------------------------------------------------------------------------------// top level function to receive time from WWVB//------------------------------------------------------------------------------int es100_receive(int dt_array[]){ // local variables int irq_status = 0; int current_timer_value; int count = 0; // enable and delay Serial.println("Enabling es100"); es100_enable(); mcu_timer_wait_us(ENABLE_DELAY_US); // start reception es100_start_rx(); Serial.print("Done with es100_start_rx, starting while(irq_status != 0x01) \n"); // loop until time received while (irq_status != 0x01) { // wait for interrupt Serial.print("Count in while(irq_status != 0x01) = "); Serial.print(count++); Serial.print("\nIRQ status going in to wait for irq_status(...)... HEX = "); // my test statement Serial.print(irq_status,HEX); Serial.print(" ---- DEC = "); Serial.print(irq_status,DEC); Serial.print("\n"); Serial.print("Waiting for interrupt ... "); // The following three are my test statements es100_wait_for_irq(); Serial.println("Interrupt received ..."); //Serial.print("Elapsed time to here..."); //Serial.print(elapsedTime); //Serial.print("\n"); // interrupt defines second boundary, so save current timer value current_timer_value = mcu_timer_read(); // read interrupt status irq_status = es100_get_irq_status(); Serial.print("IRQ status = 0x"); Serial.println(irq_status, HEX); } // End while Serial.print("IRQ status 0x01 received, now outside of while loop in function es100_receive(int dt_array[ ]) --------------------\n"); endTime = millis(); elapsedTime = endTime - beginTime; Serial.print("Elapsed time to IRQ status 0x01 received and outside of while loop in es100_receive(int dt_array[ ]) = "); Serial.print(elapsedTime); Serial.print("\n"); // read date and time Serial.print("Date and time values that are in dt_array\n"); es100_read_time(dt_array); Serial.print("Disabling the ES100 and leaving function es100_receive(..."); // disable ES100 es100_disable(); // return timer value when interrupt occurred return(current_timer_value); } // end es100_receive(int dt_array[])//------------------------------------------------------------------------------// setup function - runs once//------------------------------------------------------------------------------void setup(){ Serial.begin(9600); // Required for output to the Arduino IDE Serial.print("\nThe program is running in setup(...)\n"); // Tells me the program got ot here. pinMode(led, OUTPUT); // Required for Blnk.ino code // local variables int current_timer_value; int dt_array[DT_LENGTH]; // get start time beginTime = millis(); // initialize MCU mcu_init(); Serial.print("==================================================================\n"); Serial.print("Initialized MCU\n"); // initialize gpios mcu_gpio_set_low(GPIO_EN); Serial.print("Initialized gpios\n"); endTime = millis(); elapsedTime = endTime - beginTime; Serial.print("Elapsed time to here..."); Serial.print(elapsedTime); Serial.print("\n"); // receive time from WWVB current_timer_value = es100_receive(dt_array); // remove for testing Serial.print("\n"); Serial.print("Past receive time from WWVB statement\n"); // display date and time Serial.print("Received UTC time HEX = 20"); Serial.print(dt_array[DT_YEAR], HEX); Serial.print(":"); Serial.print(dt_array[DT_MONTH], HEX); Serial.print(":"); Serial.print(dt_array[DT_DAY], HEX); Serial.print(" "); Serial.print(dt_array[DT_HOUR], HEX); Serial.print(":"); Serial.print(dt_array[DT_MINUTE], HEX); Serial.print(":"); Serial.println(dt_array[DT_SECOND], HEX);// display date and time Serial.println("YYYY:MM:DD:hh:mm:ss.nnnn"); Serial.print("Received UTC time DEC = 20"); Serial.print(dt_array[DT_YEAR] - 6, DEC); Serial.print(":"); Serial.print(dt_array[DT_MONTH], DEC); Serial.print(":"); Serial.print(dt_array[DT_DAY], DEC); Serial.print(" "); Serial.print(dt_array[DT_HOUR], DEC); Serial.print(":"); Serial.print(dt_array[DT_MINUTE], DEC); Serial.print(":"); Serial.print(dt_array[DT_SECOND], DEC); Serial.print(" -- Minutes & seconds as decimal minutes = "); decimalMinutes = ((float)dt_array[DT_MINUTE])+(((float)dt_array[DT_SECOND])/60.0); Serial.print(decimalMinutes,DEC); Serial.println(" "); // display timer value when second occurred Serial.print("Second boundary occurred at timer count = "); Serial.println(current_timer_value); // display status register Serial.print("Status register = 0x"); Serial.println(dt_array[DT_STATUS], HEX); // display next DST transition date Serial.print("Next DST transition = month "); Serial.print(dt_array[DT_NEXT_DST_MONTH], HEX); Serial.print(", day "); Serial.print(dt_array[DT_NEXT_DST_DAY], HEX); Serial.print(", hour "); Serial.println(dt_array[DT_NEXT_DST_HOUR], HEX); endTime = millis(); elapsedTime = endTime - beginTime; Serial.print("Elapsed time to here..."); Serial.print(elapsedTime); Serial.print("\n"); Elapsed_Time_in_Minutes = (double)elapsedTime/1000/60; Serial.print("Elapsed in minutes... , "); Serial.print(Elapsed_Time_in_Minutes); Serial.print(" , Milliseconds , "); Serial.print(elapsedTime); Serial.print("\n"); // Set time on Arduino clock //setTime(06,0,0,2,3,2019); // Set time to noon January 1, 2011 hours,minutes,seconds, day,month,year (may be YYYY) setTime(dt_array[DT_HOUR], dt_array[DT_MINUTE], dt_array[DT_SECOND], dt_array[DT_DAY], dt_array[DT_MONTH], dt_array[DT_YEAR]); time_t t = now(); Serial.println("YYYY:MM:DD:hh:mm:ss.nnnn"); Serial.print(year(t),HEX); Serial.print("--"); Serial.print((long)year(t),HEX); Serial.print(":"); Serial.print((long)month(t),HEX); Serial.print(":"); Serial.print((long)day(t),HEX); Serial.print(":"); Serial.print((long)hour(t),HEX); Serial.print(":"); Serial.print((long)minute(t),HEX); Serial.print(":"); Serial.print((float)second(t),HEX); Serial.print(" \n"); Serial.print(year(t)-6); Serial.print("--"); Serial.print((long)year(t)-6); Serial.print(":"); Serial.print((long)month(t)); Serial.print(":"); Serial.print((long)day(t)); Serial.print(" "); Serial.print((long)hour(t)); Serial.print(":"); Serial.print((long)minute(t)); Serial.print(":"); Serial.print((float)second(t),4); Serial.print(" -- Minutes & seconds as decimal minutes = "); decimalMinutes = ((float)minute(t))+((float)second(t)/60.0); Serial.print(decimalMinutes,4); Serial.print(" \n"); Serial.print("==================================================================\n"); }//------------------------------------------------------------------------------// loop function - not used//------------------------------------------------------------------------------void loop() { // put your main code here, to run repeatedly: // Code frm Blink.ino tells me the program has made it to the loop function // Also see other items labeled as from Blink.ino //Serial.print("Running in loop(...) \n"); digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(led, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second // end Blink.ino code }