Skip to content

Commit 8bf6947

Browse files
committed
Implement #200, #201, #202
* Add RTC and NTP blocks * Add WiFi localIP() block * Add BLE device address block
1 parent 8f25cee commit 8bf6947

File tree

7 files changed

+355
-21
lines changed

7 files changed

+355
-21
lines changed

edit/blocks/linkit.js

+23-11
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,18 @@ Blockly.Blocks['linkit_ble_periphral'] = {
137137
}
138138
};
139139

140+
Blockly.Blocks['linkit_ble_get_address'] = {
141+
init: function() {
142+
this.setHelpUrl(Blockly.Msg.LINKIT_SET_BLE_PERIPHRAL_HELPURL);
143+
this.setColour(Blockly.Blocks.linkit.HUE);
144+
this.appendDummyInput()
145+
.appendField(Blockly.Msg.LINKIT_GET_BLE_ADDRESS);
146+
this.setOutput(true, 'String');
147+
this.setTooltip(Blockly.Msg.LINKIT_SET_BLE_PERIPHRAL_TOOLTIP);
148+
}
149+
};
150+
151+
140152
/*
141153
Blockly.Blocks['linkit_ble_periphral'] = {
142154
init: function() {
@@ -246,17 +258,6 @@ Blockly.Blocks['linkit_ble_wait_until_ready'] = {
246258
}
247259
};
248260

249-
Blockly.Blocks['linkit_ble_get_address'] = {
250-
init: function() {
251-
this.setHelpUrl(Blockly.Msg.LINKIT_SET_BLE_HELPURL);
252-
this.setColour(Blockly.Blocks.linkit.HUE);
253-
this.appendDummyInput()
254-
.appendField(Blockly.Msg.LINKIT_SET_BLE_GET_ADDRESS_TITLE);
255-
this.setOutput(true, 'String');
256-
this.setTooltip(Blockly.Msg.LINKIT_SET_BLE_TOOLTIP);
257-
}
258-
};
259-
260261
Blockly.Blocks['linkit_ble_ready'] = {
261262
init: function() {
262263
this.setHelpUrl(Blockly.Msg.LINKIT_SET_BLE_HELPURL);
@@ -774,6 +775,17 @@ Blockly.Blocks['linkit_wifi_ready'] = {
774775
}
775776
};
776777

778+
Blockly.Blocks['linkit_wifi_ip_address'] = {
779+
init: function() {
780+
this.setHelpUrl(Blockly.Msg.LINKIT_SET_WIFI_HELPURL);
781+
this.setColour(Blockly.Blocks.linkit.HUE);
782+
this.appendDummyInput()
783+
.appendField(Blockly.Msg.LINKIT_GET_WIFI_IP_TITLE);
784+
this.setOutput(true, 'String');
785+
this.setTooltip(Blockly.Msg.LINKIT_SET_WIFI_TOOLTIP);
786+
}
787+
};
788+
777789
Blockly.Blocks['linkit_wifi'] = {
778790
init: function() {
779791
this.setHelpUrl(Blockly.Msg.LINKIT_SET_WIFI_HELPURL);

edit/blocks/times.js

+109
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,112 @@ Blockly.Blocks['millis'] = {
107107
this.setTooltip(Blockly.Msg.TIMES_MILLIS_TOOLTIP);
108108
}
109109
};
110+
111+
Blockly.Blocks['ntp_get_datetime'] = {
112+
init: function() {
113+
this.setHelpUrl(Blockly.Msg.TIMES_MILLIS_HELPURL);
114+
this.setColour(Blockly.Blocks.times.HUE);
115+
this.appendDummyInput()
116+
.appendField(Blockly.Msg.TIMES_DATETIME_FROM_WIFI_APPENDTEXT);
117+
118+
// This block should return yyyy-mm-ddThh:mm:ss (based on ISO8601 but removes fractions)
119+
this.setOutput(true, "String");
120+
this.setTooltip(Blockly.Msg.TIMES_DATETIME_FROM_WIFI_TOOLTIP);
121+
122+
}
123+
};
124+
125+
Blockly.Blocks['rtc_set_time_from_string'] = {
126+
init: function() {
127+
// This block should parse the input string yyyy-mm-ddThh:mm:ss+08 (ISO8601)
128+
// and call LRTC.set() accordingly
129+
this.setHelpUrl(Blockly.Msg.TIMES_DATETIME_RTC_HELPURL);
130+
this.setColour(Blockly.Blocks.times.HUE);
131+
this.appendValueInput("TIME_STRING")
132+
.setCheck(["String", "Text"])
133+
.appendField(Blockly.Msg.TIMES_DATETIME_SET_RTC_STRING_APPENDTEXT);
134+
135+
this.setPreviousStatement(true, null);
136+
this.setNextStatement(true, null);
137+
this.setTooltip(Blockly.Msg.TIMES_DATETIME_SET_RTC_STRING_TOOLTIP);
138+
139+
}
140+
};
141+
142+
Blockly.Blocks['rtc_get_time'] = {
143+
init: function() {
144+
this.setHelpUrl(Blockly.Msg.TIMES_DATETIME_RTC_HELPURL);
145+
this.setColour(Blockly.Blocks.times.HUE);
146+
this.appendDummyInput()
147+
.appendField(Blockly.Msg.TIMES_DATETIME_GET_RTC);
148+
149+
// This block should return yyyy-mm-ddThh:mm:ss (based on ISO8601 but removes fractions)
150+
this.setOutput(true, "String");
151+
this.setTooltip(Blockly.Msg.TIMES_DATETIME_GET_RTC_TOOLTIP);
152+
}
153+
};
154+
155+
Blockly.Blocks['rtc_get_time_field'] = {
156+
init: function() {
157+
this.setHelpUrl(Blockly.Msg.TIMES_DATETIME_RTC_HELPURL);
158+
this.setColour(Blockly.Blocks.times.HUE);
159+
this.appendDummyInput()
160+
.appendField(Blockly.Msg.TIMES_DATETIME_GET_RTC_UNIT)
161+
.appendField(new Blockly.FieldDropdown([
162+
[Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_YEAR, '0'],
163+
[Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_MONTH, '1'],
164+
[Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_DAY, '2'],
165+
[Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_HOUR, '3'],
166+
[Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_MIN, '4'],
167+
[Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_SEC, '5'],
168+
]), 'FIELD');
169+
170+
this.appendValueInput("TIME_STRING")
171+
.setCheck(["String"]);
172+
173+
// This block should parsed number
174+
this.setInputsInline(true);
175+
this.setOutput(true, "Number");
176+
this.setTooltip(Blockly.Msg.TIMES_DATETIME_GET_RTC_UNIT_TOOLTIP);
177+
}
178+
};
179+
180+
Blockly.Blocks['rtc_set_time_from_number'] = {
181+
init: function() {
182+
// This block takes numerical values
183+
// and call LRTC.set() accordingly
184+
this.setHelpUrl(Blockly.Msg.TIMES_DATETIME_RTC_HELPURL);
185+
this.setColour(Blockly.Blocks.times.HUE);
186+
this.appendDummyInput()
187+
.appendField(Blockly.Msg.TIMES_DATETIME_SET_RTC_NUMBER_APPENDTEXT);
188+
189+
this.appendValueInput("YEAR")
190+
.setCheck(["Number"])
191+
.setAlign(Blockly.ALIGN_RIGHT)
192+
.appendField(Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_YEAR);
193+
this.appendValueInput("MONTH")
194+
.setCheck(["Number"])
195+
.setAlign(Blockly.ALIGN_RIGHT)
196+
.appendField(Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_MONTH);
197+
this.appendValueInput("DAY")
198+
.setCheck(["Number"])
199+
.setAlign(Blockly.ALIGN_RIGHT)
200+
.appendField(Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_DAY);
201+
this.appendValueInput("HOUR")
202+
.setCheck(["Number"])
203+
.setAlign(Blockly.ALIGN_RIGHT)
204+
.appendField(Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_HOUR);
205+
this.appendValueInput("MIN")
206+
.setCheck(["Number"])
207+
.setAlign(Blockly.ALIGN_RIGHT)
208+
.appendField(Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_MIN);
209+
this.appendValueInput("SEC")
210+
.setCheck(["Number"])
211+
.setAlign(Blockly.ALIGN_RIGHT)
212+
.appendField(Blockly.Msg.TIMES_DATETIME_RTC_APPENDTEXT_SEC);
213+
214+
this.setPreviousStatement(true, null);
215+
this.setNextStatement(true, null);
216+
this.setTooltip(Blockly.Msg.TIMES_DATETIME_SET_RTC_NUMBER_TOOLTIP);
217+
}
218+
};

edit/generators/linkit.js

+13-10
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ Blockly.Arduino.linkit_ble_periphral = function() {
137137
return code;
138138
};
139139

140+
Blockly.Arduino.linkit_ble_get_address = function() {
141+
Blockly.Arduino.definitions_['define_linkit_ble_include'] = '#include <LBLE.h>';
142+
Blockly.Arduino.setups_['define_linkit_ble_setup'] = 'LBLE.begin();';
143+
144+
var code = "LBLE.getDeviceAddress().toString()"
145+
return [code, Blockly.Arduino.ORDER_ATOMIC];
146+
};
147+
140148
/* origin:
141149
Blockly.Arduino.linkit_ble_periphral = function() {
142150
@@ -248,16 +256,6 @@ Blockly.Arduino.linkit_ble_wait_until_ready = function() {
248256
return code;
249257
};
250258

251-
Blockly.Arduino.linkit_ble_get_address = function() {
252-
253-
Blockly.Arduino.definitions_['define_linkit_ble_include'] = '#include <LBLE.h>';
254-
255-
Blockly.Arduino.setups_['define_linkit_ble_setup'] = 'LBLE.begin();';
256-
257-
var code = "LBLE.getDeviceAddress()";
258-
return [code, Blockly.Arduino.ORDER_ATOMIC];
259-
};
260-
261259
Blockly.Arduino.linkit_ble_ready = function() {
262260

263261
Blockly.Arduino.definitions_['define_linkit_ble_include'] = '#include <LBLE.h>';
@@ -493,6 +491,11 @@ Blockly.Arduino.linkit_wifi_ready_advanced = function() {
493491
return [code, Blockly.Arduino.ORDER_ATOMIC];
494492
};
495493

494+
Blockly.Arduino.linkit_wifi_ip_address = function() {
495+
var code = "WiFi.localIP().toString()";
496+
return [code, Blockly.Arduino.ORDER_ATOMIC];
497+
};
498+
496499
Blockly.Arduino.linkit_wifi_ready = function() {
497500
var code = "(WiFi.begin(_lwifi_ssid, _lwifi_pass) == WL_CONNECTED)";
498501
return [code, Blockly.Arduino.ORDER_ATOMIC];

edit/generators/times.js

+159
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,162 @@ Blockly.Arduino['micros'] = function() {
6161
var code = 'micros()';
6262
return [code,Blockly.Arduino.ORDER_ATOMIC];
6363
};
64+
65+
Blockly.Arduino['rtc_get_time'] = function() {
66+
Blockly.Arduino.definitions_['define_rtc'] = '#include <LRTC.h>';
67+
Blockly.Arduino.setups_['setup_rtc'] = 'LRTC.begin();';
68+
Blockly.Arduino.definitions_['define_rtc_get_time'] = `
69+
String get_time_from_RTC() {
70+
// get time from the RTC module
71+
LRTC.get();
72+
73+
// format to time string
74+
static char buffer[] = "YYYY-MM-DDTHH:MM:SS+08";
75+
sprintf(buffer, "%04ld-%02ld-%02ldT%02ld:%02ld:%02ld+08",
76+
LRTC.year(),
77+
LRTC.month(),
78+
LRTC.day(),
79+
LRTC.hour(),
80+
LRTC.minute(),
81+
LRTC.second());
82+
83+
return String(buffer);
84+
}\n`
85+
86+
var code = 'get_time_from_RTC()';
87+
return [code,Blockly.Arduino.ORDER_ATOMIC];
88+
};
89+
90+
Blockly.Arduino['rtc_set_time_from_number'] = function() {
91+
Blockly.Arduino.definitions_['define_rtc'] = '#include <LRTC.h>';
92+
Blockly.Arduino.setups_['setup_rtc'] = 'LRTC.begin();';
93+
94+
var year = Blockly.Arduino.valueToCode(this, 'YEAR', Blockly.Arduino.ORDER_ATOMIC) || '0'
95+
var month = Blockly.Arduino.valueToCode(this, 'MONTH', Blockly.Arduino.ORDER_ATOMIC) || '0'
96+
var day = Blockly.Arduino.valueToCode(this, 'DAY', Blockly.Arduino.ORDER_ATOMIC) || '0'
97+
var hour = Blockly.Arduino.valueToCode(this, 'HOUR', Blockly.Arduino.ORDER_ATOMIC) || '0'
98+
var min = Blockly.Arduino.valueToCode(this, 'MIN', Blockly.Arduino.ORDER_ATOMIC) || '0'
99+
var sec = Blockly.Arduino.valueToCode(this, 'SEC', Blockly.Arduino.ORDER_ATOMIC) || '0'
100+
101+
var code = `LRTC.set(${year}, ${month}, ${day}, ${hour}, ${min}, ${sec});\n`
102+
return code;
103+
};
104+
105+
Blockly.Arduino['rtc_set_time_from_string'] = function() {
106+
Blockly.Arduino.definitions_['define_rtc'] = '#include <LRTC.h>';
107+
Blockly.Arduino.setups_['setup_rtc'] = 'LRTC.begin();';
108+
Blockly.Arduino.definitions_['define_rtc_set_rtc_from_time_string'] = `
109+
void set_rtc_from_time_string(const String& time_str) {
110+
// field_index [0,1,2,3,4,5] = [Year,Month,Day,Hour,Minute,Sec]
111+
int fields[6] = {0};
112+
sscanf(time_str.c_str(), "%d-%d-%dT%d:%d:%d+08",
113+
&fields[0], &fields[1], &fields[2],
114+
&fields[3], &fields[4], &fields[5]);
115+
LRTC.set(fields[0], fields[1], fields[2],
116+
fields[3], fields[4], fields[5]);
117+
}\n`
118+
119+
var time_str = Blockly.Arduino.valueToCode(this, 'TIME_STRING', Blockly.Arduino.ORDER_ATOMIC) || '"1900-00-00T00:00:00+08"'
120+
var code = `set_rtc_from_time_string(${time_str});\n`
121+
return code;
122+
};
123+
124+
Blockly.Arduino['rtc_get_time_field'] = function() {
125+
Blockly.Arduino.definitions_['define_rtc'] = '#include <LRTC.h>';
126+
Blockly.Arduino.setups_['setup_rtc'] = 'LRTC.begin();';
127+
Blockly.Arduino.definitions_['define_rtc_get_field_from_time_string'] = `
128+
int get_field_from_time_string(const String& time_str, int field_index) {
129+
// field_index [0,1,2,3,4,5] = [Year,Month,Day,Hour,Minute,Sec]
130+
int fields[6] = {0};
131+
sscanf(time_str.c_str(), "%d-%d-%dT%d:%d:%d+08",
132+
&fields[0], &fields[1], &fields[2],
133+
&fields[3], &fields[4], &fields[5]);
134+
if(field_index < 0 || field_index > 5) {
135+
return 0;
136+
} else {
137+
return fields[field_index];
138+
}
139+
}\n`
140+
141+
var time_str = Blockly.Arduino.valueToCode(this, 'TIME_STRING', Blockly.Arduino.ORDER_ATOMIC) || '"1900-00-00T00:00:00+08"'
142+
var field_index = this.getFieldValue('FIELD')
143+
var code = `get_field_from_time_string(${time_str}, ${field_index})`
144+
return [code,Blockly.Arduino.ORDER_ATOMIC];
145+
};
146+
147+
Blockly.Arduino['ntp_get_datetime'] = function() {
148+
Blockly.Arduino.definitions_['define_udp'] = '#include <WiFiUdp.h>';
149+
Blockly.Arduino.definitions_['define_ctime'] = '#include <ctime>';
150+
Blockly.Arduino.definitions_['define_ntp_get_datetime'] = `
151+
const char *NTP_server = "time.stdtime.gov.tw";
152+
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
153+
static byte packetBuffer[NTP_PACKET_SIZE] = {0}; //buffer to hold incoming and outgoing packets
154+
const unsigned int localPort = 2390; // local port to listen for UDP packets
155+
static WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP
156+
157+
String getNetworkTime() {
158+
Udp.begin(localPort);
159+
sendNTPpacket(NTP_server); // send an NTP packet to a time server
160+
// wait to see if a reply is available
161+
delay(1000);
162+
if (Udp.parsePacket()) {
163+
// We've received a packet, read the data from it
164+
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
165+
166+
//the timestamp starts at byte 40 of the received packet and is four bytes,
167+
// or two words, long. First, esxtract the two words:
168+
const unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
169+
const unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
170+
// combine the four bytes (two words) into a long integer
171+
// this is NTP time (seconds since Jan 1 1900):
172+
const unsigned long secsSince1900 = highWord << 16 | lowWord;
173+
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
174+
const unsigned long seventyYears = 2208988800UL;
175+
// subtract seventy years:
176+
const unsigned long epoch = secsSince1900 - seventyYears;
177+
// Taiwan is UTC+8 = 8 * 60 * 60 seconds
178+
const time_t taiwan_time = epoch + (8 * 60 * 60);
179+
// const tm* pTime = gmtime(&taiwan_time);
180+
static char time_text[] = "YYYY-MM-DDTHH:MM:SS+08";
181+
strftime(time_text, sizeof(time_text), "%Y-%m-%dT%H:%M:%S+08", gmtime(&taiwan_time));
182+
return String((const char*)time_text);
183+
}
184+
185+
return String("Connection error");
186+
}
187+
188+
// send an NTP request to the time server at the given address
189+
unsigned long sendNTPpacket(const char* host) {
190+
//Serial.println("1");
191+
// set all bytes in the buffer to 0
192+
memset(packetBuffer, 0, NTP_PACKET_SIZE);
193+
// Initialize values needed to form NTP request
194+
// (see URL above for details on the packets)
195+
//Serial.println("2");
196+
packetBuffer[0] = 0b11100011; // LI, Version, Mode
197+
packetBuffer[1] = 0; // Stratum, or type of clock
198+
packetBuffer[2] = 6; // Polling Interval
199+
packetBuffer[3] = 0xEC; // Peer Clock Precision
200+
// 8 bytes of zero for Root Delay & Root Dispersion
201+
packetBuffer[12] = 49;
202+
packetBuffer[13] = 0x4E;
203+
packetBuffer[14] = 49;
204+
packetBuffer[15] = 52;
205+
206+
//Serial.println("3");
207+
208+
// all NTP fields have been given values, now
209+
// you can send a packet requesting a timestamp:
210+
Udp.beginPacket(host, 123); //NTP requests are to port 123
211+
//Serial.println("4");
212+
Udp.write(packetBuffer, NTP_PACKET_SIZE);
213+
//Serial.println("5");
214+
Udp.endPacket();
215+
//Serial.println("6");
216+
217+
return 0;
218+
}
219+
`
220+
var code = `getNetworkTime()`;
221+
return [code,Blockly.Arduino.ORDER_ATOMIC];
222+
}

0 commit comments

Comments
 (0)