Files
drivers/examples/espat/mqttclient/main.go
T

189 lines
4.0 KiB
Go

// This is a sensor station that uses a ESP8266 or ESP32 running on the device UART1.
// It creates an MQTT connection that publishes a message every second
// to an MQTT broker.
//
// In other words:
// Your computer <--> UART0 <--> MCU <--> UART1 <--> ESP8266 <--> Internet <--> MQTT broker.
//
// You must install the Paho MQTT package to build this program:
//
// go get github.com/eclipse/paho.mqtt.golang
//
package main
import (
"machine"
"math/rand"
"time"
"github.com/eclipse/paho.mqtt.golang/packets"
"tinygo.org/x/drivers/espat"
)
// access point info
const ssid = "YOURSSID"
const pass = "YOURPASS"
const useSSL = true
// IP address of the MQTT broker to use. Replace with your own info.
//const server = "test.mosquitto.org:1883"
const server = "test.mosquitto.org:8883"
// change these to connect to a different UART or pins for the ESP8266/ESP32
var (
uart = machine.UART1
tx = machine.D10
rx = machine.D11
console = machine.UART0
adaptor *espat.Device
conn espat.Conn
err error
mid uint16
topic = "tinygo"
)
func main() {
time.Sleep(3000 * time.Millisecond)
uart.Configure(machine.UARTConfig{TX: tx, RX: rx})
rand.Seed(time.Now().UnixNano())
// Init esp8266/esp32
adaptor = espat.New(uart)
adaptor.Configure()
// first check if connected
if connectToESP() {
println("Connected to wifi adaptor.")
adaptor.Echo(false)
connectToAP()
} else {
println("")
println("Unable to connect to wifi adaptor.")
return
}
// make connection
if useSSL {
println("Dialing SSL connection...")
conn, err = adaptor.DialTLS("tcp", server, nil)
if err != nil {
println("SSL connect error")
println(err)
return
}
} else {
println("Dialing TCP connection...")
conn, err = adaptor.Dial("tcp", server)
if err != nil {
println("TCP connect error")
println(err)
return
}
}
err = connectToMQTTServer()
for {
publishToMQTT()
time.Sleep(1000 * time.Millisecond)
}
// Right now this code is never reached. Need a way to trigger it...
println("Disconnecting TCP...")
conn.Close()
println("Done.")
}
// connect to ESP8266/ESP32
func connectToESP() bool {
for i := 0; i < 5; i++ {
println("Connecting to wifi adaptor...")
if adaptor.Connected() {
return true
}
time.Sleep(1 * time.Second)
}
return false
}
// connect to access point
func connectToAP() {
println("Connecting to wifi network...")
adaptor.SetWifiMode(espat.WifiModeClient)
adaptor.ConnectToAP(ssid, pass, 10)
println("Connected.")
println(adaptor.GetClientIP())
}
func connectToMQTTServer() error {
// send the MQTT connect message
connectPkt := packets.NewControlPacket(packets.Connect).(*packets.ConnectPacket)
connectPkt.Qos = 0
// connectPkt.Username = "tinygo"
// connectPkt.Password = []byte("1234")
connectPkt.ClientIdentifier = "tinygo-client-" + randomString(10)
connectPkt.ProtocolVersion = 4
connectPkt.ProtocolName = "MQTT"
connectPkt.Keepalive = 30
println("Sending MQTT connect...")
err := connectPkt.Write(conn)
if err != nil {
println("mqtt connect error")
println(err.Error())
return err
}
println("Waiting for MQTT connect...")
// TODO: handle timeout
for {
packet, _ := packets.ReadPacket(conn)
if packet != nil {
_, ok := packet.(*packets.ConnackPacket)
if ok {
println("Connected to MQTT server.")
println(packet.String())
return nil
}
}
time.Sleep(100 * time.Millisecond)
}
}
func publishToMQTT() error {
println("Publishing MQTT message...")
publish := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
publish.Qos = 0
publish.TopicName = topic
publish.Payload = []byte("Hello, mqtt\r\n")
publish.MessageID = mid
mid++
return publish.Write(conn)
}
// Returns an int >= min, < max
func randomInt(min, max int) int {
return min + rand.Intn(max-min)
}
// Generate a random string of A-Z chars with len = l
func randomString(len int) string {
bytes := make([]byte, len)
for i := 0; i < len; i++ {
bytes[i] = byte(randomInt(65, 90))
}
return string(bytes)
}