genuino101 how to set RTC from BLE central device

I am building a weather bot and want to set the internal RTC of the 101.
The 101 does not have a battery for the RTC and every time it is powered up the clock resets.
I can set it in hard code, but this means reloading the program each time.
What I want to do is get the current time from my android (or desktop) using the standard BLE CurrentTime service, when it connects and set the RTC from this characteristic.

Here is my code so far, but it is throwing errors related to the CurrentTime service. I think it is telling me I have a variable type mismatch (I always struggle with these).

I have pared it down to mostly the CurrentTime Service and the Device Information service.

Note: the device information service code works and lets me see current revision date of my code on the android. You can also pass serial number, model number, etc. if you want.

Can someone tell me what I am doing wrong, or point me to an example where someone else has pulled the datetime from BLE (I haven't found any examples).

/* Arduino 101 
  -test for current time service */
 #define BotName "WeatherBot"  
 #define Version "12/29/16 "     //0x2A28 utf8s
 //#define MfgName  "JLD"        //0x2A29 utf8s
 //#define ModelNum  "000001"    //0x2A24 utf8s
 //#define SerialNum "000001"    //0x2A25 utf8s 
 //#define HardwareRev "0001"    //0x2A27 utf8s
 //#define FirmwareRev "0001"    //0x2A26 utf8s
 //#define SystemID "000001"     //0x2A23 uint40
  
  #include <CurieBLE.h>  

//  initialize Real time clock 
  #include <CurieTime.h>
  char DateString[16];
  char TimeString[16];
  char date[16]; 
//initialize variables
  unsigned long currentMillis = millis();  
  unsigned long prevSensor = 0;
  const int sensorFreq = 1000;

  bool serialFlag = 1;
  char state = 'z';
  char cmd, LCmd  = ' ';
  #define ledPin    13
  #define pwrMOSFET 13
  bool pwrFlag = 1;
   
BLEPeripheral blePeripheral;
bool BLEstatus = false;

//* create Device Info Service and Characteristic
BLEService DeviceInfoService("180A");
  BLECharacteristic SoftwareRevision("2A28", BLERead, 10); 


// change this it throws errors !!
//create Current Time Service and Characteristic
BLEService CurrentTimeService("1805");
  BLECharacteristic CurrentTimeCharacteristic("2A2B", BLERead | BLEWrite | BLENotify); //exacttime 256
  timezone, uint16 dstoffset

void setup()  
 {
   Serial.begin(115200); 
              

    //* set advertised local name and service UUID:
  blePeripheral.setLocalName(BotName);   //make a unique name
    // assign event handlers
  blePeripheral.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  blePeripheral.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
 
//* change this to get time from BLE central 
     // set the current time to 14:27:00, December 14th, 2015
  //setTime(14, 27, 00, 14, 12, 2016);
  blePeripheral.setAdvertisedServiceUuid(CurrentTimeService.uuid());
  blePeripheral.addAttribute(CurrentTimeService);
    blePeripheral.addAttribute(CurrentTimeCharacteristic); 
    CurrentTimeCharacteristic.setEventHandler(BLEWritten, CurrentTimeCharacteristicWritten);
//*/
  
  blePeripheral.setAdvertisedServiceUuid(DeviceInfoService.uuid());
  blePeripheral.addAttribute(DeviceInfoService);
    blePeripheral.addAttribute(SoftwareRevision); 
      static const uint8_t Version2[] = Version;
      SoftwareRevision.setValue(Version2,10);

 
     // begin advertising BLE service:
  blePeripheral.begin();
  
  if (serialFlag)
     { delay(5000); //while(!Serial); 
       Serial.println(F("initialization complete"));
       Serial.println(F("Bluetooth device active, waiting for connections..."));  
       Serial.print(F("Starting! ")); Serial.print(BotName);
       Serial.print(F("  ")); Serial.println(Version); 
     }    
} // end of setup 
 
void loop()  
 {
   //* check to see if character received from serial port       
    if (!Serial.available() < 1) 
       {
         cmd = Serial.read();  
         decode (cmd);
       } // end of check serial */
               
  //*    
    if (BLEstatus )  
      { 
        //  only do this if BLE is connected      
        if(currentMillis - prevSensor > sensorFreq)
          {
                    
          }
      } // end if central connected actions  */ 
   
} // end of void loop


void blePeripheralConnectHandler(BLECentral& central)
 {   
   BLEstatus = true;
   digitalWrite(ledPin, HIGH);
   decode('x');     
   if (serialFlag)
      {
        Serial.print(F("Connected event, central: "));
        Serial.println(central.address());
      }    
 } // end of connect handler   *****/

void blePeripheralDisconnectHandler(BLECentral& central) 
 {   
   BLEstatus = false;
   digitalWrite(ledPin, LOW);
   pwrFlag  = 0;
   decode('z');
   if (serialFlag)
      {
        Serial.print(F("Disconnected event, central: "));
        Serial.println(central.address());
      }
   delay(100);
 } // end of disconnect handler  
     
void CurrentTimeCharacteristicWritten(BLECentral& central, BLECharacteristic& characteristic) 
 { 
   if (characteristic.value()) // NULL pointer check
      {    
        //date[] = *characteristic.value();      // This throws error for wrong type     
        Serial.print("time Characteristic event, written: ");
        //Serial.println(date);
      } 
 } // end of datetime written 

void decode(char a)
   {
       LCmd = a;
       if (serialFlag)
          {Serial.println(a);}
          
       switch(a) 
        {
          case '=': // toggle serial output flag
              serialFlag=!serialFlag; 
             break;                    
          case 'z': // toggle power flag off
              state = 'z';     
              pwrFlag = 0; 
              digitalWrite (pwrMOSFET, pwrFlag);
             break;             
          case 'x': // toggle power flag on
              state = 'x';     
              pwrFlag = 1; 
              digitalWrite (pwrMOSFET, pwrFlag);
             break;     
  } // end of switch case
}   // end of decode

but it is throwing errors

So, you threw them away? I thought that you wanted help with them. Guess I was wrong.

Sorry forgot to include the error message

Arduino: 1.8.0 (Windows 10), Board: "Arduino/Genuino 101"

weathertest:46: error: no matching function for call to 'BLECharacteristic::BLECharacteristic(const char [5], int)'

   BLECharacteristic CurrentTimeCharacteristic("2A2B", BLERead | BLEWrite | BLENotify); //exacttime 256

                                                                                     ^

d:\Grizzly\Documents\Arduino\dummy\weathertest\weathertest.ino:46:85: note: candidates are:

In file included from C:\Users\Grizzly\AppData\Local\Arduino15\packages\Intel\hardware\arc32\1.0.7\libraries\CurieBLE\src/CurieBLE.h:20:0,

                 from d:\Grizzly\Documents\Arduino\dummy\weathertest\weathertest.ino:15:

C:\Users\Grizzly\AppData\Local\Arduino15\packages\Intel\hardware\arc32\1.0.7\libraries\CurieBLE\src/BLECharacteristic.h:80:5: note: BLECharacteristic::BLECharacteristic(const char*, unsigned char, const char*)

     BLECharacteristic(const char* uuid,

     ^

C:\Users\Grizzly\AppData\Local\Arduino15\packages\Intel\hardware\arc32\1.0.7\libraries\CurieBLE\src/BLECharacteristic.h:80:5: note:   candidate expects 3 arguments, 2 provided

C:\Users\Grizzly\AppData\Local\Arduino15\packages\Intel\hardware\arc32\1.0.7\libraries\CurieBLE\src/BLECharacteristic.h:69:5: note: BLECharacteristic::BLECharacteristic(const char*, unsigned char, short unsigned int)

     BLECharacteristic(const char* uuid,

     ^

C:\Users\Grizzly\AppData\Local\Arduino15\packages\Intel\hardware\arc32\1.0.7\libraries\CurieBLE\src/BLECharacteristic.h:69:5: note:   candidate expects 3 arguments, 2 provided

C:\Users\Grizzly\AppData\Local\Arduino15\packages\Intel\hardware\arc32\1.0.7\libraries\CurieBLE\src/BLECharacteristic.h:60:7: note: constexpr BLECharacteristic::BLECharacteristic(const BLECharacteristic&)

 class BLECharacteristic : public BLEAttribute {

       ^

C:\Users\Grizzly\AppData\Local\Arduino15\packages\Intel\hardware\arc32\1.0.7\libraries\CurieBLE\src/BLECharacteristic.h:60:7: note:   candidate expects 1 argument, 2 provided

exit status 1
no matching function for call to 'BLECharacteristic::BLECharacteristic(const char [5], int)'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Shows the ways to call the constructor for the BLECharacteristic class. All of the constructors seem to require three arguments. Why are you supplying only two?

Thanks Paul.
This was an oversight. Adding the 3rd parameter solved the first of my problems.
With a few other tweaks I am now able to see and update the characteristic from my android.
Now to get it into the right format.
If I get this working, I will post the final code for others.
Jeff

Hello Jeff,

Have you resolve your BLE characteristic problem ?
I seem to have the same and don't find the solution...

Hi,

I finaly use this solution to set RTC from BLE :

// Create BLE Services
BLEService TemperatureService("180F"); 
  // Create BLE Temperature Characteristic - standard 16-bit characteristic UUID - remote clients will be able to get notifications if this characteristic changes
  BLEUnsignedCharCharacteristic TemperatureCharacteristic("2A19", BLERead | BLENotify); 

BLEService CurrentTimeService("1805");
  BLECharacteristic DateTimeCharacteristic("2A08", BLERead | BLEWrite , 7); // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.date_time.xml


void setup() {      
  //MyPlainProtocol.begin(115200);                  // initial the Serial with PlainProtocol https://www.dfrobot.com/blog-69.html
                                                    // Problem because MyPlainProtocol.begin() wait for serial connection
  Serial.begin(115200);
  
  BLE.begin();                                      // initialize the BLE hardware
  
  // Set a local name for the BLE device. When the phone (central device) connects to this peripheral, the local name will appear on the phone to identify the connected periperal.
  BLE.setLocalName("Aquarium");                     

  // set the UUID for the services this peripheral advertises  
  BLE.setAdvertisedService(TemperatureService);   
  BLE.setAdvertisedService(CurrentTimeService);          
  
  // add the characteristics to the services
  TemperatureService.addCharacteristic(TemperatureCharacteristic); 
  CurrentTimeService.addCharacteristic(DateTimeCharacteristic); 
  
  // Add the BLE services
  BLE.addService(TemperatureService);                   
  BLE.addService(CurrentTimeService);   
  
  /* Start advertising BLE.  It will start continuously transmitting BLE
  advertising packets and will be visible to remote BLE central devices
  until it receives a new connection */
  BLE.advertise(); 



void loop() {
  delay(1000);  

  BLE.poll();  
 
  now = rtc.now(); 
  RTC_Display(now);

 // const unsigned char DateTimeCharArray[7] = { 226, 7, 5, 8, 9, 3, 0 };   // 2018 (0x07E2 - 7 226) May 8th , 09:03:00
  uint8_t DateTimeCharArray[7];
  DateTimeCharArray[0] = now.year() & 0x00FF; // LSB (0xE2) 2018 = 0x07E2
  DateTimeCharArray[1] = now.year() >> 8;     // MSB (0x07)
  DateTimeCharArray[2] = now.month();  
  DateTimeCharArray[3] = now.day();
  DateTimeCharArray[4] = now.hour();
  DateTimeCharArray[5] = now.minute();  
  DateTimeCharArray[6] = now.second();    

  DateTimeCharacteristic.setValue(DateTimeCharArray, 7);  // and update date time characteristic
1 Like