diff --git a/README.md b/README.md index ced1860..87ee08a 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,31 @@ Use ``||point||`` to open or close point dispay. Use ``||clear||`` to clean display. +### Grove - UART WiFi V2 + +Connect to a WiFi and send data to ThinkSpeak or IFTTT, specify the UART tx and rx pin. + +```blocks +grove.setupWifi( + SerialPin.P15, + SerialPin.P1, + BaudRate.BaudRate115200, + "test-ssid", + "test-passwd" +) + +basic.forever(() => { + if (grove.wifiOK()) { + basic.showIcon(IconNames.Yes) + } else { + basic.showIcon(IconNames.No) + } + grove.sendToThinkSpeak("write_api_key", 1, 2, 3, 4, 5, 6, 7, 8) + grove.sendToIFTTT("ifttt_event", "ifttt_key", "hello", 'micro', 'bit') + basic.pause(60000) +}) +``` + ## License MIT diff --git a/main.ts b/main.ts index bf2d3a2..7ae9ed9 100644 --- a/main.ts +++ b/main.ts @@ -88,7 +88,7 @@ enum GroveJoystickKey { * Functions to operate Grove module. */ //% weight=10 color=#9F79EE icon="\uf1b3" block="Grove" -//% groups='["4-Digit","Ultrasonic","Gesture","Thumbjoystick"]' +//% groups='["4-Digit","Ultrasonic","Gesture","Thumbjoystick","UartWiFi"]' namespace grove { /** * @@ -638,4 +638,170 @@ namespace grove { }) } + + let isWifiConnected = false; + /** + * Setup Grove - Uart WiFi V2 to connect to Wi-Fi + */ + //% block="Setup Wifi|TX %txPin|RX %rxPin|Baud rate %baudrate|SSID = %ssid|Password = %passwd" + //% group="UartWiFi" + //% txPin.defl=SerialPin.P15 + //% rxPin.defl=SerialPin.P1 + //% baudRate.defl=BaudRate.BaudRate115200 + export function setupWifi(txPin: SerialPin, rxPin: SerialPin, baudRate: BaudRate, ssid: string, passwd: string) { + let result = 0 + + isWifiConnected = false + + serial.redirect( + txPin, + rxPin, + baudRate + ) + + sendAtCmd("AT") + result = waitAtResponse("OK", "ERROR", "None", 1000) + + sendAtCmd("AT+CWMODE=1") + result = waitAtResponse("OK", "ERROR", "None", 1000) + + sendAtCmd(`AT+CWJAP="${ssid}","${passwd}"`) + result = waitAtResponse("WIFI GOT IP", "ERROR", "None", 20000) + + if (result == 1) { + isWifiConnected = true + } + } + + /** + * Check if Grove - Uart WiFi V2 is connected to Wifi + */ + //% block="Wifi OK?" + //% group="UartWiFi" + export function wifiOK() { + return isWifiConnected + } + + /** + * Send data to ThinkSpeak + */ + //% block="Send Data to your ThinkSpeak Channel|Write API Key %apiKey|Field1 %field1|Field2 %field2|Field3 %field3|Field4 %field4|Field5 %field5|Field6 %field6|Field7 %field7|Field8 %field8" + //% group="UartWiFi" + //% apiKey.defl="your Write API Key" + export function sendToThinkSpeak(apiKey: string, field1: number, field2: number, field3: number, field4: number, field5: number, field6: number, field7: number, field8: number) { + let result = 0 + let retry = 2 + + // close the previous TCP connection + if (isWifiConnected) { + sendAtCmd("AT+CIPCLOSE") + waitAtResponse("OK", "ERROR", "None", 2000) + } + + while (isWifiConnected && retry > 0) { + retry = retry - 1; + // establish TCP connection + sendAtCmd("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",80") + result = waitAtResponse("OK", "ALREADY CONNECTED", "ERROR", 2000) + if (result == 3) continue + + let data = "GET /update?api_key=" + apiKey + if (!isNaN(field1)) data = data + "&field1=" + field1 + if (!isNaN(field2)) data = data + "&field2=" + field2 + if (!isNaN(field3)) data = data + "&field3=" + field3 + if (!isNaN(field4)) data = data + "&field4=" + field4 + if (!isNaN(field5)) data = data + "&field5=" + field5 + if (!isNaN(field6)) data = data + "&field6=" + field6 + if (!isNaN(field7)) data = data + "&field7=" + field7 + if (!isNaN(field8)) data = data + "&field8=" + field8 + + sendAtCmd("AT+CIPSEND=" + (data.length + 2)) + result = waitAtResponse(">", "OK", "ERROR", 2000) + if (result == 3) continue + sendAtCmd(data) + result = waitAtResponse("SEND OK", "SEND FAIL", "ERROR", 5000) + + // // close the TCP connection + // sendAtCmd("AT+CIPCLOSE") + // waitAtResponse("OK", "ERROR", "None", 2000) + + if (result == 1) break + } + } + + /** + * Send data to IFTTT + */ + //% block="Send Data to your IFTTT Event|Event %event|Key %key|value1 %value1|value2 %value2|value3 %value3" + //% group="UartWiFi" + //% event.defl="your Event" + //% key.defl="your Key" + //% value1.defl="hello" + //% value2.defl="micro" + //% value3.defl="bit" + export function sendToIFTTT(event: string, key: string, value1: string, value2: string, value3: string) { + let result = 0 + let retry = 2 + + // close the previous TCP connection + if (isWifiConnected) { + sendAtCmd("AT+CIPCLOSE") + waitAtResponse("OK", "ERROR", "None", 2000) + } + + while (isWifiConnected && retry > 0) { + retry = retry - 1; + // establish TCP connection + sendAtCmd("AT+CIPSTART=\"TCP\",\"maker.ifttt.com\",80") + result = waitAtResponse("OK", "ALREADY CONNECTED", "ERROR", 2000) + if (result == 3) continue + + let data = "GET /trigger/" + event + "/with/key/" + key + data = data + "?value1=" + value1 + data = data + "&value2=" + value2 + data = data + "&value3=" + value3 + data = data + " HTTP/1.1" + data = data + "\u000D\u000A" + data = data + "User-Agent: curl/7.58.0" + data = data + "\u000D\u000A" + data = data + "Host: maker.ifttt.com" + data = data + "\u000D\u000A" + data = data + "Accept: */*" + data = data + "\u000D\u000A" + + sendAtCmd("AT+CIPSEND=" + (data.length + 2)) + result = waitAtResponse(">", "OK", "ERROR", 2000) + if (result == 3) continue + sendAtCmd(data) + result = waitAtResponse("SEND OK", "SEND FAIL", "ERROR", 5000) + + // // close the TCP connection + // sendAtCmd("AT+CIPCLOSE") + // waitAtResponse("OK", "ERROR", "None", 2000) + + if (result == 1) break + } + } + + + function waitAtResponse(target1: string, target2: string, target3: string, timeout: number) { + let buffer = "" + let start = input.runningTime() + + while ((input.runningTime() - start) < timeout) { + buffer += serial.readString() + + if (buffer.includes(target1)) return 1 + if (buffer.includes(target2)) return 2 + if (buffer.includes(target3)) return 3 + + basic.pause(100) + } + + return 0 + } + + function sendAtCmd(cmd: string) { + serial.writeString(cmd + "\u000D\u000A") + } } \ No newline at end of file diff --git a/pxt.json b/pxt.json index e07641a..299d426 100644 --- a/pxt.json +++ b/pxt.json @@ -1,6 +1,6 @@ { "name": "Grove", - "version": "0.2.7", + "version": "0.3.0", "description": "A Microsoft MakeCode package for Seeed Studio Grove module", "license": "MIT", "dependencies": { diff --git a/test.ts b/test.ts index 729d026..3997a88 100644 --- a/test.ts +++ b/test.ts @@ -1,4 +1,12 @@ let _4Digit = grove.createDisplay(DigitalPin.C16, DigitalPin.C17) +grove.setupWifi( + SerialPin.P15, + SerialPin.P1, + BaudRate.BaudRate115200, + "test-ssid", + "test-passwd" +) + basic.forever(function () { _4Digit.bit(6, 1) }) \ No newline at end of file