diff --git a/examples/net/mqttclient/espat.go b/examples/net/mqttclient/natiu/espat.go similarity index 100% rename from examples/net/mqttclient/espat.go rename to examples/net/mqttclient/natiu/espat.go diff --git a/examples/net/mqttclient/natiu/main.go b/examples/net/mqttclient/natiu/main.go new file mode 100644 index 0000000..8faa9a9 --- /dev/null +++ b/examples/net/mqttclient/natiu/main.go @@ -0,0 +1,136 @@ +// This example is an MQTT client built with the natiu-mqtt package. It sends +// machine.CPUFrequency() readings to the broker every second for 10 seconds. +// +// Note: It may be necessary to increase the stack size when using +// paho.mqtt.golang. Use the -stack-size=4KB command line option. + +package main + +import ( + "context" + "errors" + "fmt" + "io" + "log" + "machine" + "math/rand" + "net" + "time" + + mqtt "github.com/soypat/natiu-mqtt" +) + +var ( + ssid string + pass string + broker string = "test.mosquitto.org:1883" + topic string = "cpu/freq" +) + +func main() { + waitSerial() + + if err := netdev.NetConnect(); err != nil { + log.Fatal(err) + } + + clientId := "tinygo-client-" + randomString(10) + fmt.Printf("ClientId: %s\n", clientId) + + // Get a transport for MQTT packets + fmt.Printf("Connecting to MQTT broker at %s\n", broker) + conn, err := net.Dial("tcp", broker) + if err != nil { + log.Fatal(err) + } + defer conn.Close() + + // Create new client + client := mqtt.NewClient(mqtt.ClientConfig{ + Decoder: mqtt.DecoderNoAlloc{make([]byte, 1500)}, + OnPub: func(_ mqtt.Header, _ mqtt.VariablesPublish, r io.Reader) error { + message, _ := io.ReadAll(r) + fmt.Printf("Message %s received on topic %s\n", string(message), topic) + return nil + }, + }) + + // Connect client + var varconn mqtt.VariablesConnect + varconn.SetDefaultMQTT([]byte(clientId)) + ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) + err = client.Connect(ctx, conn, &varconn) + if err != nil { + log.Fatal("failed to connect: ", err) + } + + // Subscribe to topic + ctx, _ = context.WithTimeout(context.Background(), 10*time.Second) + err = client.Subscribe(ctx, mqtt.VariablesSubscribe{ + PacketIdentifier: 23, + TopicFilters: []mqtt.SubscribeRequest{ + {TopicFilter: []byte(topic), QoS: mqtt.QoS0}, + }, + }) + if err != nil { + log.Fatal("failed to subscribe to", topic, err) + } + fmt.Printf("Subscribed to topic %s\n", topic) + + // Publish on topic + pubFlags, _ := mqtt.NewPublishFlags(mqtt.QoS0, false, false) + pubVar := mqtt.VariablesPublish{ + TopicName: []byte(topic), + } + + for i := 0; i < 10; i++ { + if !client.IsConnected() { + log.Fatal("client disconnected: ", client.Err()) + } + + freq := float32(machine.CPUFrequency()) / 1000000 + payload := fmt.Sprintf("%.02fMhz", freq) + + pubVar.PacketIdentifier++ + err = client.PublishPayload(pubFlags, pubVar, []byte(payload)) + if err != nil { + log.Fatal("error transmitting message: ", err) + } + + time.Sleep(time.Second) + + conn.SetReadDeadline(time.Now().Add(10*time.Second)) + err = client.HandleNext() + if err != nil { + log.Fatal("handle next: ", err) + } + + } + + client.Disconnect(errors.New("disconnected gracefully")) + + for { + select {} + } +} + +// 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) +} + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} diff --git a/examples/net/mqttclient/rtl8720dn.go b/examples/net/mqttclient/natiu/rtl8720dn.go similarity index 100% rename from examples/net/mqttclient/rtl8720dn.go rename to examples/net/mqttclient/natiu/rtl8720dn.go diff --git a/examples/net/mqttclient/wifinina.go b/examples/net/mqttclient/natiu/wifinina.go similarity index 100% rename from examples/net/mqttclient/wifinina.go rename to examples/net/mqttclient/natiu/wifinina.go diff --git a/examples/net/mqttclient/paho/espat.go b/examples/net/mqttclient/paho/espat.go new file mode 100644 index 0000000..3a197fe --- /dev/null +++ b/examples/net/mqttclient/paho/espat.go @@ -0,0 +1,23 @@ +//go:build challenger_rp2040 + +// +build: challenger_rp2040 + +package main + +import ( + "machine" + + "tinygo.org/x/drivers/espat" +) + +var cfg = espat.Config{ + // WiFi AP credentials + Ssid: ssid, + Passphrase: pass, + // UART + Uart: machine.UART1, + Tx: machine.UART1_TX_PIN, + Rx: machine.UART1_RX_PIN, +} + +var netdev = espat.New(&cfg) diff --git a/examples/net/mqttclient/main.go b/examples/net/mqttclient/paho/main.go similarity index 92% rename from examples/net/mqttclient/main.go rename to examples/net/mqttclient/paho/main.go index 9f0ade3..8fe6a8a 100644 --- a/examples/net/mqttclient/main.go +++ b/examples/net/mqttclient/paho/main.go @@ -1,5 +1,5 @@ -// This example is a MQTT client. It sends machine.ReadTemparature() readings -// to the broker every second for 10 seconds. +// This example is an MQTT client built with the paho-mqtt package. It sends +// machine.CPUFrequency() readings to the broker every second for 10 seconds. // // Note: It may be necessary to increase the stack size when using // paho.mqtt.golang. Use the -stack-size=4KB command line option. @@ -76,6 +76,10 @@ func main() { } client.Disconnect(100) + + for { + select {} + } } // Returns an int >= min, < max diff --git a/examples/net/mqttclient/paho/rtl8720dn.go b/examples/net/mqttclient/paho/rtl8720dn.go new file mode 100644 index 0000000..94d5277 --- /dev/null +++ b/examples/net/mqttclient/paho/rtl8720dn.go @@ -0,0 +1,29 @@ +//go:build wioterminal + +// +build: wioterminal + +package main + +import ( + "machine" + "time" + + "tinygo.org/x/drivers/rtl8720dn" +) + +var cfg = rtl8720dn.Config{ + // WiFi AP credentials + Ssid: ssid, + Passphrase: pass, + // Device + En: machine.RTL8720D_CHIP_PU, + // UART + Uart: machine.UART3, + Tx: machine.PB24, + Rx: machine.PC24, + Baudrate: 614400, + // Watchdog (set to 0 to disable) + WatchdogTimeout: time.Duration(20 * time.Second), +} + +var netdev = rtl8720dn.New(&cfg) diff --git a/examples/net/mqttclient/paho/wifinina.go b/examples/net/mqttclient/paho/wifinina.go new file mode 100644 index 0000000..a135548 --- /dev/null +++ b/examples/net/mqttclient/paho/wifinina.go @@ -0,0 +1,33 @@ +//go:build pyportal || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 + +// +build: pyportal nano_rp2040 metro_m4_airlift arduino_mkrwifi1010 matrixportal_m4 + +package main + +import ( + "machine" + "time" + + "tinygo.org/x/drivers/wifinina" +) + +var cfg = wifinina.Config{ + // WiFi AP credentials + Ssid: ssid, + Passphrase: pass, + // Configure SPI for 8Mhz, Mode 0, MSB First + Spi: machine.NINA_SPI, + Freq: 8 * 1e6, + Sdo: machine.NINA_SDO, + Sdi: machine.NINA_SDI, + Sck: machine.NINA_SCK, + // Device pins + Cs: machine.NINA_CS, + Ack: machine.NINA_ACK, + Gpio0: machine.NINA_GPIO0, + Resetn: machine.NINA_RESETN, + // Watchdog (set to 0 to disable) + WatchdogTimeout: time.Duration(20 * time.Second), +} + +var netdev = wifinina.New(&cfg)