Everything in the .vbs script is all in Windows. SendKeys sends keystroke entries into the keyboard buffer of the program named in AppActivate. The keys sent are defined in the function at the bottom of the script, which constitute a timestamp.
If AppActivate is pointing to a running Windows program that's connected to an Arduino through a COM port, then that program will receive the keystrokes just as if you had typed them in, and send them to the Arduino.
The Arduino's loop() function will check for Serial.available on each loop, and collect received bytes into a buffer until it receives a CR or LF, and then it processes what's in the buffer. If it recognizes a timestamp, then it would update its RTC with the new data.
So the Arduino is just doing whatever it's doing until it sees incoming bytes from the serial port, which it has to process. Nothing is automatic, and only the Arduino talks to the RTC. Aside from the time it takes to do all this, there should be no conflict unless the Arduino is receiving other data from the serial monitor. But normally it's transmitting data to the serial monitor, which shouldn't be a problem.
/*
* TimeSerial.pde
* example code illustrating Time library set through serial port messages.
*
* Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970)
* you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2013
T1357041600
*
* A Processing example sketch to automatically send the messages is included in the download
* On Linux, you can use "date +T%s\n > /dev/ttyACM0" (UTC time zone)
*/
#include <TimeLib.h>
#define TIME_HEADER "T" // Header tag for serial time sync message
#define TIME_REQUEST 7 // ASCII bell character requests a time sync message
void setup() {
Serial.begin(9600);
while (!Serial) ; // Needed for Leonardo only
pinMode(13, OUTPUT);
setSyncProvider( requestSync); //set function to call when sync required
Serial.println("Waiting for sync message");
}
void loop(){
if (Serial.available()) {
processSyncMessage();
}
if (timeStatus()!= timeNotSet) {
digitalClockDisplay();
}
if (timeStatus() == timeSet) {
digitalWrite(13, HIGH); // LED on if synced
} else {
digitalWrite(13, LOW); // LED off if needs refresh
}
delay(1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void processSyncMessage() {
unsigned long pctime;
const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013
if(Serial.find(TIME_HEADER)) {
pctime = Serial.parseInt();
if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013)
setTime(pctime); // Sync Arduino clock to the time received on the serial port
}
}
}
time_t requestSync()
{
Serial.write(TIME_REQUEST);
return 0; // the time will be sent later in response to serial mesg
}
...the call to the processSyncMessage() is the "it" watching for serial input and doing stuff with it. That sketch doesn't use an RTC, but with an RTC attached, one would need to add code to update the RTC as well.
First let me thank you all for the quality of your responses. It has been quite instructive.
My plan (solar environment) is to keep the Arduino active during the day and put it to sleep at night. (wake up and sleep determined by preset alarms from the RTC)
If the unit is put to sleep @ 5pm (RTC Int1), it is my understanding that I could make an IDE request @ 8pm to either update the RTC time or download some SD card data and put it back to sleep .
The Arduino would wake up the following morning (RTC Int1) and the "Main Sketch" would go on it's merry way.
It's my understanding that an IDE request will be serviced regardless of SleepMode and the RTC will continue to keep time as long as PWR/bat is available.
Typically the RTC would wake up the Arduino, and then the Arduino would go to sleep on its own when it's finished doing what it needs to do - after setting the next alarm time.
I don't know that incoming serial activity would wake up an Arduino if it's in power-down sleep. But I guess you could always connect the RxD pin to another IO pin that's set to wake up the processor.
Again I am still learning. If I am using the IDE request to wake up the Arduinoand If that request is too "large", do I risk overflowing the keyboard buffer because it does take some time for the wake up to complete?
If the above is true, would it be better to initially send a short IDE wake up request with a confirmation of "wake up complete" and then have the IDE send the more extensive RTC or SD card read.
I don't know how long it takes the serial function to wake up. But just sending a single byte would make sense. Or you could send a single byte, then wait for a response, and keep doing that until you get that response. Then send the real message.
Going back to set the RTC, here's a simple manual method that will give you 1 second accuracy, if you can time your return key on the dot
A setting string is formatted like so T2025,3,12,15,25,0 which would be be a time slightly in the future. When your system clock hits the time you hit [Return].
//Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include "RTClib.h"
#define TIME_HEADER "T"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void setup () {
Serial.begin(115200);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
Serial.println("Set the RTC by sending \"T\"year, month, day, hour, minute, second");
Serial.println("For example T2025,3,12,15,25,0 when your pc system clock hits the time you");
Serial.println("hit [Return]");
Serial.println("If you are off by a second or so, have another go!!!");
/*
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
// When time needs to be re-set on a previously configured device, the
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
*/
}
char timeStr[10] = {0};
char dateStr[12] = {0};
uint32_t lastTime = 0;
bool Set = false;
void printDateTime() {
DateTime now = rtc.now();
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
sprintf(dateStr, " %d/%d/%d", now.day(), now.month(), now.year());
sprintf(timeStr, " %02d:%02d:%02d", now.hour(), now.minute(), now.second());
Serial.print(dateStr);
Serial.println(timeStr);
Serial.println(now.unixtime());
Serial.print("Temperature: ");
Serial.print(rtc.getTemperature());
Serial.println("°C\n");
}
void loop () {
if (Set) {
if (millis() - lastTime > 1000) {
lastTime = millis();
printDateTime();
}
}
////////Set the RTC by sending "T"year, month, day, hour, minute, second//////
////////For example T2025,3,12,15,25,0 when your pc system clock hits the time you
////////hit [Return]
////////If you are off by a second or so, have another go!!!
////////Get your local time @ https://time.is
while (Serial.available()) {
char c = Serial.read();
delay(10);
if (c == 'T') {
uint16_t yr = Serial.parseInt();
uint8_t mo = Serial.parseInt();
uint8_t dy = Serial.parseInt();
uint8_t hr = Serial.parseInt();
uint8_t mn = Serial.parseInt();
uint8_t sc = Serial.parseInt();
rtc.adjust(DateTime(yr, mo, dy, hr, mn, sc));
Serial.println("RTC was Set at...");
printDateTime();
Set = true;
}
//Get an Epoch converter (Google Chrome Extension) you can input a future time
// and send the resulting stamp with a "U" prefix, for example U1741809988
// copy/paste the above to try
else if (c == 'U') {
uint32_t Unix = Serial.parseInt();
rtc.adjust(DateTime(Unix));
Serial.println("RTC was Set at...");
printDateTime();
Set = true;
}
}
}
The code is a combination of available examples discussed earlier.
This may be a little off topic. I am not a conspiracy nut but I do wonder what would happen if the Internet was no longer available due to solar flare, ISP destroyed by terrorist, nuclear armageddon, or the client can no longer afford it.
Therefore, I am considering the attached. If one plans for the worst, it won't happen.
This would allow me to check and readjust the RTC @ solar noon. In the solar environment, Solarnoon is an ideal reference point.
I realize that Solarnoon time varies (±25min) throughout the year. Time stamping and storing the interupts would allow for adjustments and predicting the equinox.
Some circuit adjustments should be added in my spare time.
add resistors to load the cell output to prevent triggers on low light days.
add RC filter to op amp inputs to preclude false triggers. (lightning, airplane landing lights, Police searchlights for evasive criminals, etc)
If I missed something?
Things were opposite until I realized you had a negative latitude.
You are correct. I have decided that placing the each solar cell @ 45 degrees /\ tepee style would give me a sharper interrupt.