From 05c0aaaaa5f892ae5c18ca74b6c51e447b5eb628 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 2 May 2023 19:25:19 +0200 Subject: [PATCH 1/3] wifinina: small timing adjustments in Configure() to better ensure device reset Signed-off-by: deadprogram --- wifinina/wifinina.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wifinina/wifinina.go b/wifinina/wifinina.go index d0b294c82..f6d0b07f4 100644 --- a/wifinina/wifinina.go +++ b/wifinina/wifinina.go @@ -151,12 +151,12 @@ func (d *Device) Configure() { d.GPIO0.High() d.CS.High() d.RESET.Low() - time.Sleep(1 * time.Millisecond) + time.Sleep(10 * time.Millisecond) d.RESET.High() - time.Sleep(1 * time.Millisecond) + time.Sleep(750 * time.Millisecond) d.GPIO0.Low() - d.GPIO0.Configure(machine.PinConfig{Mode: machine.PinInput}) + d.GPIO0.Configure(machine.PinConfig{Mode: machine.PinInputPullup}) } From 8312ab8ed562a651cefe07e2c68e13bb09e5df71 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 2 May 2023 19:27:51 +0200 Subject: [PATCH 2/3] examples/wifinina: improve connectToAP() and other needed minor corrections Signed-off-by: deadprogram --- examples/wifinina/connect/main.go | 26 ++++++++---- examples/wifinina/http-get/main.go | 31 ++++++++++---- examples/wifinina/mqttclient/main.go | 24 +++++++---- examples/wifinina/mqttsub/main.go | 25 +++++++---- examples/wifinina/ntpclient/main.go | 32 ++++++++++---- examples/wifinina/tcpclient/main.go | 32 ++++++++++---- examples/wifinina/tlsclient/main.go | 32 ++++++++++---- examples/wifinina/udpstation/main.go | 36 ++++++++++++---- examples/wifinina/webclient/main.go | 35 +++++++++++----- examples/wifinina/webserver/main.go | 63 +++++++++++++++++++--------- 10 files changed, 239 insertions(+), 97 deletions(-) diff --git a/examples/wifinina/connect/main.go b/examples/wifinina/connect/main.go index e758ce4f6..a42e647aa 100644 --- a/examples/wifinina/connect/main.go +++ b/examples/wifinina/connect/main.go @@ -128,17 +128,29 @@ func waitSerial() { } } +const retriesBeforeFailure = 3 + // connect to access point func connectToAP() { time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return } } - println("Connected.") + // error connecting to AP + failMessage(err.Error()) +} + +func failMessage(msg string) { + for { + println(msg) + time.Sleep(1 * time.Second) + } } diff --git a/examples/wifinina/http-get/main.go b/examples/wifinina/http-get/main.go index cc44142ab..6fb57002d 100644 --- a/examples/wifinina/http-get/main.go +++ b/examples/wifinina/http-get/main.go @@ -74,6 +74,7 @@ func main() { waitSerial() connectToAP() + displayIP() // You can send and receive cookies in the following way // import "tinygo.org/x/drivers/net/http/cookiejar" @@ -131,28 +132,42 @@ func waitSerial() { } } +const retriesBeforeFailure = 3 + // connect to access point func connectToAP() { time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return } } - println("Connected.") + // error connecting to AP + failMessage(err.Error()) +} +func displayIP() { ip, _, _, err := adaptor.GetIP() for ; err != nil; ip, _, _, err = adaptor.GetIP() { message(err.Error()) time.Sleep(1 * time.Second) } - message(ip.String()) + message("IP address: " + ip.String()) } func message(msg string) { println(msg, "\r") } + +func failMessage(msg string) { + for { + println(msg) + time.Sleep(1 * time.Second) + } +} diff --git a/examples/wifinina/mqttclient/main.go b/examples/wifinina/mqttclient/main.go index c03ed92cb..8ffbf572c 100644 --- a/examples/wifinina/mqttclient/main.go +++ b/examples/wifinina/mqttclient/main.go @@ -65,6 +65,7 @@ func main() { adaptor.Configure() connectToAP() + displayIP() opts := mqtt.NewClientOptions() opts.AddBroker(server).SetClientID("tinygo-client-" + randomString(10)) @@ -101,26 +102,33 @@ func main() { println("Done.") } +const retriesBeforeFailure = 3 + // connect to access point func connectToAP() { time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return } } - println("Connected.") + // error connecting to AP + failMessage(err.Error()) +} +func displayIP() { ip, _, _, err := adaptor.GetIP() for ; err != nil; ip, _, _, err = adaptor.GetIP() { println(err.Error()) time.Sleep(1 * time.Second) } - println(ip.String()) + println("IP address: " + ip.String()) } // Returns an int >= min, < max diff --git a/examples/wifinina/mqttsub/main.go b/examples/wifinina/mqttsub/main.go index b19ed1ecf..c03d96ff5 100644 --- a/examples/wifinina/mqttsub/main.go +++ b/examples/wifinina/mqttsub/main.go @@ -71,6 +71,7 @@ func main() { adaptor.Configure() connectToAP() + displayIP() opts := mqtt.NewClientOptions() opts.AddBroker(server).SetClientID("tinygo-client-" + randomString(10)) @@ -113,27 +114,33 @@ func publishing() { } } +const retriesBeforeFailure = 3 + // connect to access point func connectToAP() { time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return } } - println("Connected.") + // error connecting to AP + failMessage(err.Error()) +} - time.Sleep(2 * time.Second) +func displayIP() { ip, _, _, err := adaptor.GetIP() for ; err != nil; ip, _, _, err = adaptor.GetIP() { println(err.Error()) time.Sleep(1 * time.Second) } - println(ip.String()) + println("IP address: " + ip.String()) } // Returns an int >= min, < max diff --git a/examples/wifinina/ntpclient/main.go b/examples/wifinina/ntpclient/main.go index 606e54bbf..7c15eb675 100644 --- a/examples/wifinina/ntpclient/main.go +++ b/examples/wifinina/ntpclient/main.go @@ -61,6 +61,7 @@ func main() { waitSerial() connectToAP() + displayIP() // now make UDP connection ip := net.ParseIP(ntpHost) @@ -149,29 +150,42 @@ func clearBuffer() { } } +const retriesBeforeFailure = 3 + // connect to access point func connectToAP() { time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return } } - println("Connected.") + // error connecting to AP + failMessage(err.Error()) +} - time.Sleep(2 * time.Second) +func displayIP() { ip, _, _, err := adaptor.GetIP() for ; err != nil; ip, _, _, err = adaptor.GetIP() { message(err.Error()) time.Sleep(1 * time.Second) } - message(ip.String()) + message("IP address: " + ip.String()) } func message(format string, args ...interface{}) { println(fmt.Sprintf(format, args...), "\r") } + +func failMessage(msg string) { + for { + println(msg) + time.Sleep(1 * time.Second) + } +} diff --git a/examples/wifinina/tcpclient/main.go b/examples/wifinina/tcpclient/main.go index a51a91006..770c6dd53 100644 --- a/examples/wifinina/tcpclient/main.go +++ b/examples/wifinina/tcpclient/main.go @@ -56,6 +56,7 @@ func main() { adaptor.Configure() connectToAP() + displayIP() for { sendBatch() @@ -111,29 +112,42 @@ func sendBatch() { conn.Close() } +const retriesBeforeFailure = 3 + // connect to access point func connectToAP() { time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return } } - println("Connected.") + // error connecting to AP + failMessage(err.Error()) +} - time.Sleep(2 * time.Second) +func displayIP() { ip, _, _, err := adaptor.GetIP() for ; err != nil; ip, _, _, err = adaptor.GetIP() { message(err.Error()) time.Sleep(1 * time.Second) } - message(ip.String()) + message("IP address: " + ip.String()) } func message(msg string) { println(msg, "\r") } + +func failMessage(msg string) { + for { + println(msg) + time.Sleep(1 * time.Second) + } +} diff --git a/examples/wifinina/tlsclient/main.go b/examples/wifinina/tlsclient/main.go index 9e50e8970..2e1e57eb2 100644 --- a/examples/wifinina/tlsclient/main.go +++ b/examples/wifinina/tlsclient/main.go @@ -66,6 +66,7 @@ func main() { waitSerial() connectToAP() + displayIP() for { readConnection() @@ -121,29 +122,42 @@ func makeHTTPSRequest() { lastRequestTime = time.Now() } +const retriesBeforeFailure = 3 + // connect to access point func connectToAP() { time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return } } - println("Connected.") + // error connecting to AP + failMessage(err.Error()) +} - time.Sleep(2 * time.Second) +func displayIP() { ip, _, _, err := adaptor.GetIP() for ; err != nil; ip, _, _, err = adaptor.GetIP() { message(err.Error()) time.Sleep(1 * time.Second) } - message(ip.String()) + message("IP address: " + ip.String()) } func message(msg string) { println(msg, "\r") } + +func failMessage(msg string) { + for { + println(msg) + time.Sleep(1 * time.Second) + } +} diff --git a/examples/wifinina/udpstation/main.go b/examples/wifinina/udpstation/main.go index 7c921068e..08169946f 100644 --- a/examples/wifinina/udpstation/main.go +++ b/examples/wifinina/udpstation/main.go @@ -50,6 +50,7 @@ func main() { // connect to access point connectToAP() + displayIP() // now make UDP connection ip := net.ParseIP(hubIP) @@ -57,7 +58,10 @@ func main() { laddr := &net.UDPAddr{Port: 2222} println("Dialing UDP connection...") - conn, _ := net.DialUDP("udp", laddr, raddr) + conn, err := net.DialUDP("udp", laddr, raddr) + if err != nil { + failMessage(err.Error()) + } for { // send data @@ -74,28 +78,42 @@ func main() { println("Done.") } +const retriesBeforeFailure = 3 + // connect to access point func connectToAP() { time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return } } - println("Connected.") + // error connecting to AP + failMessage(err.Error()) +} +func displayIP() { ip, _, _, err := adaptor.GetIP() for ; err != nil; ip, _, _, err = adaptor.GetIP() { message(err.Error()) time.Sleep(1 * time.Second) } - message(ip.String()) + message("IP address: " + ip.String()) } func message(msg string) { println(msg, "\r") } + +func failMessage(msg string) { + for { + println(msg) + time.Sleep(1 * time.Second) + } +} diff --git a/examples/wifinina/webclient/main.go b/examples/wifinina/webclient/main.go index e8968fefd..7df2dc951 100644 --- a/examples/wifinina/webclient/main.go +++ b/examples/wifinina/webclient/main.go @@ -20,8 +20,8 @@ var ( pass string ) -// IP address of the server aka "hub". Replace with your own info. -const server = "tinygo.org" +// IP address of the "example.com" server. Replace with your own info. +const server = "93.184.216.34" // these are the default pins for the Arduino Nano33 IoT. // change these to connect to a different UART or pins for the ESP8266/ESP32 @@ -63,6 +63,7 @@ func main() { waitSerial() connectToAP() + displayIP() for { readConnection() @@ -123,28 +124,42 @@ func makeHTTPRequest() { lastRequestTime = time.Now() } +const retriesBeforeFailure = 3 + // connect to access point func connectToAP() { time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return } } - println("Connected.") + // error connecting to AP + failMessage(err.Error()) +} +func displayIP() { ip, _, _, err := adaptor.GetIP() for ; err != nil; ip, _, _, err = adaptor.GetIP() { message(err.Error()) time.Sleep(1 * time.Second) } - message(ip.String()) + message("IP address: " + ip.String()) } func message(msg string) { println(msg, "\r") } + +func failMessage(msg string) { + for { + println(msg) + time.Sleep(1 * time.Second) + } +} diff --git a/examples/wifinina/webserver/main.go b/examples/wifinina/webserver/main.go index f8bf65eba..254739b58 100644 --- a/examples/wifinina/webserver/main.go +++ b/examples/wifinina/webserver/main.go @@ -27,6 +27,11 @@ var ( pass string ) +var ( + // this is the ESP chip that has the WIFININA firmware flashed on it + adaptor *wifinina.Device +) + var led = machine.LED func main() { @@ -49,31 +54,15 @@ func run() error { SCK: machine.NINA_SCK, }) - adaptor := wifinina.New(spi, + adaptor = wifinina.New(spi, machine.NINA_CS, machine.NINA_ACK, machine.NINA_GPIO0, machine.NINA_RESETN) adaptor.Configure() - time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { - return err - } - - println("Connected.") - - time.Sleep(2 * time.Second) - ip, subnet, gateway, err := adaptor.GetIP() - if err != nil { - return err - } - - fmt.Printf("IP Address : %s\r\n", ip) - fmt.Printf("Mask : %s\r\n", subnet) - fmt.Printf("Gateway : %s\r\n", gateway) + connectToAP() + displayIP() http.UseDriver(adaptor) @@ -204,6 +193,42 @@ func cnt(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, `{"cnt": %d}`, counter) } +const retriesBeforeFailure = 3 + +// connect to access point +func connectToAP() { + time.Sleep(2 * time.Second) + var err error + for i := 0; i < retriesBeforeFailure; i++ { + println("Connecting to " + ssid) + err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) + if err == nil { + println("Connected.") + + return + } + } + + // error connecting to AP + failMessage(err.Error()) +} + +func displayIP() { + ip, _, _, err := adaptor.GetIP() + for ; err != nil; ip, _, _, err = adaptor.GetIP() { + message(err.Error()) + time.Sleep(1 * time.Second) + } + message("IP address: " + ip.String()) +} + func message(msg string) { println(msg, "\r") } + +func failMessage(msg string) { + for { + println(msg) + time.Sleep(1 * time.Second) + } +} From 1a618b623c67f588ee2e6908082f3d4dd92e4a36 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Tue, 2 May 2023 22:54:25 +0200 Subject: [PATCH 3/3] wifinina: add ResetIsHigh to control the behavior of the RESET pin for boards like the Arduino MKR 1010 Signed-off-by: deadprogram --- wifinina/wifinina.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/wifinina/wifinina.go b/wifinina/wifinina.go index f6d0b07f4..9e2d6c81c 100644 --- a/wifinina/wifinina.go +++ b/wifinina/wifinina.go @@ -126,6 +126,12 @@ type Device struct { ip uint32 port uint16 mu sync.Mutex + + // ResetIsHigh controls if the RESET signal to the processor + // should be High or Low (the default). Set this to true + // before calling Configure() for boards such as the Arduino MKR 1010, + // where the reset signal needs to go high instead of low. + ResetIsHigh bool } // New returns a new Wifinina device. @@ -139,6 +145,8 @@ func New(bus drivers.SPI, csPin, ackPin, gpio0Pin, resetPin machine.Pin) *Device } } +// Configure sets the needed pin settings and performs a reset +// of the WiFi device. func (d *Device) Configure() { net.UseDriver(d) pinUseDevice(d) @@ -150,14 +158,15 @@ func (d *Device) Configure() { d.GPIO0.High() d.CS.High() - d.RESET.Low() + + d.RESET.Set(d.ResetIsHigh) time.Sleep(10 * time.Millisecond) - d.RESET.High() + + d.RESET.Set(!d.ResetIsHigh) time.Sleep(750 * time.Millisecond) d.GPIO0.Low() d.GPIO0.Configure(machine.PinConfig{Mode: machine.PinInputPullup}) - } // ----------- client methods (should this be a separate struct?) ------------