Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96df6b18b2 | ||
|
|
c64162453a | ||
|
|
fa4ff3da22 | ||
|
|
854654aae4 |
25
README.md
25
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
|
||||
|
||||
231
main.ts
231
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 {
|
||||
/**
|
||||
*
|
||||
@@ -452,7 +452,68 @@ namespace grove {
|
||||
let joystick = new GroveJoystick();
|
||||
let paj7620 = new PAJ7620();
|
||||
// adapted to Calliope mini V2 Core by M.Klein 17.09.2020
|
||||
|
||||
/**
|
||||
* Create a new driver of Grove - Ultrasonic Sensor to measure distances in cm
|
||||
* @param pin signal pin of ultrasonic ranger module
|
||||
*/
|
||||
//% blockId=grove_ultrasonic_centimeters_v2 block="Ultrasonic Sensor (in cm) at for V2|%pin"
|
||||
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
|
||||
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250"
|
||||
//% group="Ultrasonic" pin.defl=DigitalPin.C16
|
||||
|
||||
export function measureInCentimetersV2(pin: DigitalPin): number
|
||||
{
|
||||
let duration = 0;
|
||||
let RangeInCentimeters = 0;
|
||||
|
||||
pins.digitalWritePin(pin, 0);
|
||||
control.waitMicros(2);
|
||||
pins.digitalWritePin(pin, 1);
|
||||
control.waitMicros(20);
|
||||
pins.digitalWritePin(pin, 0);
|
||||
duration = pins.pulseIn(pin, PulseValue.High, 50000); // Max duration 50 ms
|
||||
|
||||
RangeInCentimeters = duration * 153 / 44 / 2 / 100 ;
|
||||
|
||||
if(RangeInCentimeters > 0) distanceBackup = RangeInCentimeters;
|
||||
else RangeInCentimeters = distanceBackup;
|
||||
|
||||
basic.pause(50);
|
||||
|
||||
return RangeInCentimeters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new driver Grove - Ultrasonic Sensor to measure distances in inch
|
||||
* @param pin signal pin of ultrasonic ranger module
|
||||
*/
|
||||
//% blockId=grove_ultrasonic_inches_v2 block="Ultrasonic Sensor (in inch) at for V2|%pin"
|
||||
//% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4
|
||||
//% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250"
|
||||
//% group="Ultrasonic" pin.defl=DigitalPin.C16
|
||||
export function measureInInchesV2(pin: DigitalPin): number
|
||||
{
|
||||
let duration = 0;
|
||||
let RangeInInches = 0;
|
||||
|
||||
pins.digitalWritePin(pin, 0);
|
||||
control.waitMicros(2);
|
||||
pins.digitalWritePin(pin, 1);
|
||||
control.waitMicros(20);
|
||||
pins.digitalWritePin(pin, 0);
|
||||
duration = pins.pulseIn(pin, PulseValue.High, 100000); // Max duration 100 ms
|
||||
|
||||
RangeInInches = duration * 153 / 113 / 2 / 100;
|
||||
|
||||
if(RangeInInches > 0) distanceBackup = RangeInInches;
|
||||
else RangeInInches = distanceBackup;
|
||||
|
||||
basic.pause(50);
|
||||
|
||||
return RangeInInches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new driver of Grove - Ultrasonic Sensor to measure distances in cm
|
||||
* @param pin signal pin of ultrasonic ranger module
|
||||
@@ -638,4 +699,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")
|
||||
}
|
||||
}
|
||||
|
||||
2
pxt.json
2
pxt.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Grove",
|
||||
"version": "0.2.7",
|
||||
"version": "0.4.0",
|
||||
"description": "A Microsoft MakeCode package for Seeed Studio Grove module",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
Reference in New Issue
Block a user