├── LICENSE ├── README.md ├── controller.go ├── digital ├── digital.go └── digital_test.go ├── go.mod ├── go.sum ├── random ├── random.go └── random_test.go ├── serial ├── serial.go └── serial_test.go ├── timer └── timer.go └── wifi ├── client.go ├── wifi.go └── wifi_test.go /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2022 Andreas Geiß 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32 Controller 2 | 3 | [![License](https://img.shields.io/github/license/andygeiss/esp32)](https://github.com/andygeiss/esp32-controller/blob/master/LICENSE) 4 | [![Releases](https://img.shields.io/github/v/release/andygeiss/esp32)](https://github.com/andygeiss/esp32-controller/releases) 5 | [![Go Report Card](https://goreportcard.com/badge/github.com/andygeiss/esp32)](https://goreportcard.com/report/github.com/andygeiss/esp32) 6 | [![Maintainability](https://api.codeclimate.com/v1/badges/3658b2bdb86b0c27ae20/maintainability)](https://codeclimate.com/github/andygeiss/esp32-controller/maintainability) 7 | 8 | Provide an API for mapping Golang into Arduino code, which can be used by [ESP Transpiler](https://github.com/andygeiss/esp32-transpiler) 9 | 10 | ## API Functionality 11 | 12 | * [digital-io/pinmode](https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/) 13 | * [digital-io/digitalwrite](https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/) 14 | * [random-numbers/random](https://www.arduino.cc/reference/en/language/functions/random-numbers/random/) 15 | * [random-numbers/randomseed](https://www.arduino.cc/reference/en/language/functions/random-numbers/randomseed/) 16 | * [serial/available](https://www.arduino.cc/reference/en/language/functions/communication/serial/available/) 17 | * [serial/begin](https://www.arduino.cc/reference/en/language/functions/communication/serial/begin/) 18 | * [serial/print](https://www.arduino.cc/reference/en/language/functions/communication/serial/print/) 19 | * [serial/println](https://www.arduino.cc/reference/en/language/functions/communication/serial/println/) 20 | * [time/delay](https://www.arduino.cc/reference/en/language/functions/time/delay/) 21 | * [WiFiBSSID](https://www.arduino.cc/en/Reference/WiFiBSSID) 22 | * [WiFiBegin](https://www.arduino.cc/en/Reference/WiFiBegin) 23 | * [WiFiDisconnect](https://www.arduino.cc/en/Reference/WiFiDisconnect) 24 | * [WiFiEncryptionType](https://www.arduino.cc/en/Reference/WiFiEncryptionType) 25 | * [WiFiLocalIP](https://www.arduino.cc/en/Reference/WiFiLocalIP) 26 | * [WiFiRSSI](https://www.arduino.cc/en/Reference/WiFiRSSI) 27 | * [WiFiScanNetworks](https://www.arduino.cc/en/Reference/WiFiScanNetworks) 28 | * [WiFiSetDns](https://www.arduino.cc/en/Reference/WiFiSetDns) 29 | * [WiFiStatus](https://www.arduino.cc/en/Reference/WiFiStatus) 30 | * [WiFiSSID](https://www.arduino.cc/en/Reference/WiFiSSID) 31 | -------------------------------------------------------------------------------- /controller.go: -------------------------------------------------------------------------------- 1 | package esp32_controller 2 | 3 | // Controller specifies the behaviour of a system which can be setup initially and is able to loop a specific business logic. 4 | type Controller interface { 5 | Loop() error 6 | Setup() error 7 | } 8 | -------------------------------------------------------------------------------- /digital/digital.go: -------------------------------------------------------------------------------- 1 | package digital 2 | 3 | const ( 4 | // High ... 5 | High = 1 6 | // Low ... 7 | Low = 0 8 | // ModeInput ... 9 | ModeInput = 0 10 | // ModeOutput ... 11 | ModeOutput = 1 12 | // PinsMax ... 13 | PinsMax = 48 14 | ) 15 | 16 | var ( 17 | // GPIOModes ... 18 | GPIOModes = make(map[int]int, PinsMax) 19 | // GPIOValues ... 20 | GPIOValues = make(map[int]int, PinsMax) 21 | ) 22 | 23 | // IsPinValid ... 24 | func IsPinValid(pin int) bool { 25 | return pin <= PinsMax && pin > 0 26 | } 27 | 28 | // PinMode configures the specified pin to behave either as an input or an output. 29 | // @see: https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/ 30 | func PinMode(pin, mode int) { 31 | if IsPinValid(pin) { 32 | GPIOModes[pin] = mode 33 | } 34 | } 35 | 36 | // Write sets a HIGH or a LOW value to a digital pin. 37 | // @see: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/ 38 | func Write(pin, value int) { 39 | if IsPinValid(pin) { 40 | GPIOValues[pin] = value 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /digital/digital_test.go: -------------------------------------------------------------------------------- 1 | package digital_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/andygeiss/esp32-controller/digital" 7 | "github.com/andygeiss/utils/assert" 8 | ) 9 | 10 | func TestDigitalWrite(t *testing.T) { 11 | pin := 1 12 | digital.GPIOValues[pin] = digital.Low 13 | digital.Write(pin, digital.High) 14 | val := digital.GPIOValues[pin] 15 | assert.That("val is set to high", t, val, digital.High) 16 | } 17 | 18 | func TestPinMode(t *testing.T) { 19 | pin := 1 20 | digital.GPIOModes[pin] = digital.ModeInput 21 | digital.PinMode(pin, digital.ModeOutput) 22 | mode := digital.GPIOModes[pin] 23 | assert.That("mode is set to output", t, mode, digital.ModeOutput) 24 | } 25 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/andygeiss/esp32-controller 2 | 3 | go 1.19 4 | 5 | require github.com/andygeiss/utils v0.9.1 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/andygeiss/utils v0.9.1 h1:PFFgmdwNDO2/bHA/4F7/fozifH+lPyuMBAhsBuTLGf8= 2 | github.com/andygeiss/utils v0.9.1/go.mod h1:Jatj6UsFNUMgf+9vPeMZ9il72nARlhMvc54r7AiPPiU= 3 | -------------------------------------------------------------------------------- /random/random.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import "math/rand" 4 | 5 | // Num returns pseudo-random numbers. 6 | // @see: https://www.arduino.cc/reference/en/language/functions/random-numbers/random/ 7 | func Num(max int) int { 8 | return rand.Intn(max) 9 | } 10 | 11 | // NumBetween returns pseudo-random numbers between min and max. 12 | // @see: https://www.arduino.cc/reference/en/language/functions/random-numbers/random/ 13 | func NumBetween(min, max int) int { 14 | return rand.Intn(min) + (max - min) 15 | } 16 | 17 | // Seed initializes the pseudo-random number generator, causing it to start at an arbitrary point in its random sequence. 18 | // @see: https://www.arduino.cc/reference/en/language/functions/random-numbers/randomseed/ 19 | func Seed(seed int64) { 20 | rand.Seed(seed) 21 | } 22 | -------------------------------------------------------------------------------- /random/random_test.go: -------------------------------------------------------------------------------- 1 | package random_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/andygeiss/esp32-controller/random" 7 | "github.com/andygeiss/utils/assert" 8 | ) 9 | 10 | func TestNum(t *testing.T) { 11 | num := random.Num(10) 12 | assert.That("num is max 10", t, num <= 10, true) 13 | } 14 | 15 | func TestNumXY(t *testing.T) { 16 | x := random.Num(100) 17 | y := random.Num(100) 18 | assert.That("x and y are not equal", t, x != y, true) 19 | } 20 | 21 | func TestNumBetween(t *testing.T) { 22 | num := random.NumBetween(100, 200) 23 | between100And200 := num >= 100 && num <= 200 24 | assert.That("num is between 100 and 200", t, between100And200, true) 25 | } 26 | 27 | func TestSeed(t *testing.T) { 28 | random.Seed(42) 29 | x := random.Num(100) 30 | y := random.Num(100) 31 | assert.That("x and y are not equal", t, x != y, true) 32 | assert.That("x is max 100", t, x <= 100, true) 33 | assert.That("y is max 100", t, y <= 100, true) 34 | } 35 | -------------------------------------------------------------------------------- /serial/serial.go: -------------------------------------------------------------------------------- 1 | package serial 2 | 3 | import "fmt" 4 | 5 | const ( 6 | // BaudRate300 ... 7 | BaudRate300 = 300 8 | // BaudRate600 ... 9 | BaudRate600 = 600 10 | // BaudRate1200 ... 11 | BaudRate1200 = 1200 12 | // BaudRate2400 ... 13 | BaudRate2400 = 2400 14 | // BaudRate4800 ... 15 | BaudRate4800 = 4800 16 | // BaudRate9600 ... 17 | BaudRate9600 = 9600 18 | // BaudRate14400 ... 19 | BaudRate14400 = 14400 20 | // BaudRate19200 ... 21 | BaudRate19200 = 19200 22 | // BaudRate28800 ... 23 | BaudRate28800 = 28800 24 | // BaudRate38400 ... 25 | BaudRate38400 = 38400 26 | // BaudRate57600 ... 27 | BaudRate57600 = 57600 28 | // BaudRate115200 ... 29 | BaudRate115200 = 115200 30 | ) 31 | 32 | var ( 33 | // AvailableN ... 34 | AvailableN = 0 35 | // Baud ... 36 | Baud = 0 37 | ) 38 | 39 | // Available gets the number of bytes (characters) available for reading from the serial port. 40 | // @see: https://www.arduino.cc/reference/en/language/functions/communication/serial/available/ 41 | func Available() int { 42 | return AvailableN 43 | } 44 | 45 | // Begin sets the data rate in bits per second (baud) for serial data transmission. 46 | // @see: https://www.arduino.cc/reference/en/language/functions/communication/serial/begin/ 47 | func Begin(baud int) { 48 | AvailableN = 1 49 | Baud = baud 50 | } 51 | 52 | // Print prints data to the serial port as human-readable ASCII text. 53 | // @see: https://www.arduino.cc/reference/en/language/functions/communication/serial/print/ 54 | func Print(val interface{}) { 55 | fmt.Print(val) 56 | } 57 | 58 | // Println prints data to the serial port as human-readable ASCII text followed by a carriage return character (ASCII 13, or '\r') and a newline character (ASCII 10, or '\n'). 59 | // @see: https://www.arduino.cc/reference/en/language/functions/communication/serial/println/ 60 | func Println(val interface{}) { 61 | fmt.Println(val) 62 | } 63 | -------------------------------------------------------------------------------- /serial/serial_test.go: -------------------------------------------------------------------------------- 1 | package serial_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/andygeiss/esp32-controller/serial" 7 | "github.com/andygeiss/utils/assert" 8 | ) 9 | 10 | func TestSerialBegin(t *testing.T) { 11 | baud := serial.BaudRate115200 12 | serial.Baud = 0 13 | serial.Begin(baud) 14 | assert.That("baud rate is 115200", t, serial.Baud, serial.BaudRate115200) 15 | } 16 | -------------------------------------------------------------------------------- /timer/timer.go: -------------------------------------------------------------------------------- 1 | package timer 2 | 3 | import "time" 4 | 5 | // Delay pauses the program for the amount of time (in milliseconds) specified as parameter. 6 | // @see: https://www.arduino.cc/reference/en/language/functions/time/delay/ 7 | func Delay(ms int) { 8 | done := make(chan bool) 9 | go func(ms int) { 10 | time.Sleep(time.Millisecond * time.Duration(ms)) 11 | done <- true 12 | }(ms) 13 | select { 14 | case <-done: 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /wifi/client.go: -------------------------------------------------------------------------------- 1 | package wifi 2 | 3 | import "fmt" 4 | 5 | // Client ... 6 | type Client struct{} 7 | 8 | // Connect to the IP address and port specified in the constructor. 9 | // The return value indicates success or failure. 10 | // connect() also supports DNS lookups when using a domain name (ex:google.com). 11 | // @see: https://www.arduino.cc/en/Reference/WiFiClientConnect 12 | func (c *Client) Connect(host string, port int) bool { 13 | return true 14 | } 15 | 16 | // Print data, followed by a carriage return and newline, to the server a client is connected to. 17 | // Prints numbers as a sequence of digits, each an ASCII character (e.g. the number 123 is sent as the three characters '1', '2', '3'). 18 | // @see: https://www.arduino.cc/en/Reference/WiFiClientPrintln 19 | func (c *Client) Println(data interface{}) int { 20 | fmt.Println(data) 21 | return 0 22 | } 23 | 24 | // Write data to the server the client is connected to. 25 | // Return the number of characters written. 26 | // It is not necessary to read this value. 27 | // @see: https://www.arduino.cc/en/Reference/WiFiClientWrite 28 | func (c *Client) Write(data interface{}) int { 29 | fmt.Print(data) 30 | return 0 31 | } 32 | -------------------------------------------------------------------------------- /wifi/wifi.go: -------------------------------------------------------------------------------- 1 | package wifi 2 | 3 | // @see: https://www.arduino.cc/en/Reference/WiFi 4 | 5 | // IPAddress ... 6 | type IPAddress struct { 7 | A int 8 | B int 9 | C int 10 | D int 11 | } 12 | 13 | const ( 14 | // EncryptionTypeAuto ... 15 | EncryptionTypeAuto = 8 16 | // EncryptionTypeCCMP ... 17 | EncryptionTypeCCMP = 4 18 | // EncryptionTypeNone ... 19 | EncryptionTypeNone = 7 20 | // EncryptionTypeTKIP ... 21 | EncryptionTypeTKIP = 2 22 | // EncryptionTypeWEP ... 23 | EncryptionTypeWEP = 5 24 | // MaxSocketNum ... 25 | MaxSocketNum = 4096 26 | // StatusConnected ... 27 | StatusConnected = 3 28 | // StatusConnectionLost ... 29 | StatusConnectionLost = 4 30 | // StatusConnectFailed ... 31 | StatusConnectFailed = 5 32 | // StatusDisconnected ... 33 | StatusDisconnected = 6 34 | // StatusIdle ... 35 | StatusIdle = 0 36 | // StatusNoShield ... 37 | StatusNoShield = 255 38 | // StatusNoSSIDAvailable ... 39 | StatusNoSSIDAvailable = 1 40 | // StatusScanCompleted ... 41 | StatusScanCompleted = 2 42 | ) 43 | 44 | var ( 45 | // CurrentBSSID ... 46 | CurrentBSSID = []int{0, 0, 0, 0, 0, 0, 0, 0} 47 | // CurrentDNS ... 48 | CurrentDNS = []int{0, 0, 0, 0} 49 | // CurrentEncryptionType ... 50 | CurrentEncryptionType = 7 51 | // CurrentGateway ... 52 | CurrentGateway = &IPAddress{127, 0, 0, 255} 53 | // CurrentLocalIP ... 54 | CurrentLocalIP = &IPAddress{127, 0, 0, 1} 55 | // CurrentNetworks ... 56 | CurrentNetworks = 0 57 | // CurrentRSSI ... 58 | CurrentRSSI = -1 59 | // CurrentSSID ... 60 | CurrentSSID = "" 61 | // CurrentStatus ... 62 | CurrentStatus = StatusIdle 63 | // SocketPort ... 64 | SocketPort = make(map[int]int, MaxSocketNum) 65 | // SocketState ... 66 | SocketState = make(map[int]int, MaxSocketNum) 67 | ) 68 | 69 | // BSSID gets the MAC address of the routher you are connected to. 70 | // @see: https://www.arduino.cc/en/Reference/WiFiBSSID 71 | func BSSID() []int { 72 | return CurrentBSSID 73 | } 74 | 75 | // Begin initializes the WiFi library's network settings and provides the current status. 76 | // @see: https://www.arduino.cc/en/Reference/WiFiBegin 77 | func Begin(ssid string) { 78 | CurrentRSSI = 0 79 | CurrentSSID = ssid 80 | CurrentStatus = StatusConnected 81 | } 82 | 83 | // BeginEncrypted initializes the WiFi library's network settings and provides the current status. 84 | // @see: https://www.arduino.cc/en/Reference/WiFiBegin 85 | func BeginEncrypted(ssid, passphrase string) { 86 | CurrentRSSI = 0 87 | CurrentSSID = ssid 88 | CurrentStatus = StatusConnected 89 | } 90 | 91 | // Disconnect disconnects the WiFi shield from the current network. 92 | // @see: https://www.arduino.cc/en/Reference/WiFiDisconnect 93 | func Disconnect() { 94 | CurrentStatus = StatusIdle 95 | } 96 | 97 | // EncryptionType gets the encryption type of the current network. 98 | // @see: https://www.arduino.cc/en/Reference/WiFiEncryptionType 99 | func EncryptionType() int { 100 | return CurrentEncryptionType 101 | } 102 | 103 | // HostByName ... 104 | func HostByName(hostname string, addr string) int { 105 | return 0 106 | } 107 | 108 | // LocalIP gets the WiFi shield's IP address. 109 | // @see: https://www.arduino.cc/en/Reference/WiFiLocalIP 110 | func LocalIP() *IPAddress { 111 | return CurrentLocalIP 112 | } 113 | 114 | // RSSI gets the signal strength of the connection to the router. 115 | // @see: https://www.arduino.cc/en/Reference/WiFiRSSI 116 | func RSSI() int { 117 | return CurrentRSSI 118 | } 119 | 120 | // ScanNetworks scans for available WiFi networks and returns the discovered number. 121 | // @see: https://www.arduino.cc/en/Reference/WiFiScanNetworks 122 | func ScanNetworks() int { 123 | return CurrentNetworks 124 | } 125 | 126 | // SetDNS allows you to configure the DNS (Domain Name System) server. 127 | // @see: https://www.arduino.cc/en/Reference/WiFiSetDns 128 | func SetDNS(dns []int) { 129 | CurrentDNS = dns 130 | } 131 | 132 | // Status returns the connection status. 133 | // @see: https://www.arduino.cc/en/Reference/WiFiStatus 134 | func Status() int { 135 | return CurrentStatus 136 | } 137 | 138 | // SSID gets the SSID of the current network. 139 | // @see: https://www.arduino.cc/en/Reference/WiFiSSID 140 | func SSID() string { 141 | return CurrentSSID 142 | } 143 | -------------------------------------------------------------------------------- /wifi/wifi_test.go: -------------------------------------------------------------------------------- 1 | package wifi_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/andygeiss/esp32-controller/wifi" 7 | "github.com/andygeiss/utils/assert" 8 | ) 9 | 10 | func TestWifiBegin(t *testing.T) { 11 | ssid := "test" 12 | wifi.CurrentStatus = wifi.StatusIdle 13 | wifi.Begin(ssid) 14 | assert.That("current status is connected", t, wifi.CurrentStatus, wifi.StatusConnected) 15 | } 16 | 17 | func TestWifiBeginEncrypted(t *testing.T) { 18 | ssid := "test" 19 | passphrase := "passphrase" 20 | ipv4 := &wifi.IPAddress{127, 0, 0, 1} 21 | wifi.CurrentStatus = wifi.StatusIdle 22 | wifi.BeginEncrypted(ssid, passphrase) 23 | assert.That("current status is connected", t, wifi.CurrentStatus, wifi.StatusConnected) 24 | assert.That("current local ip is ipv4", t, wifi.CurrentLocalIP, ipv4) 25 | } 26 | func TestWifiDisBegin(t *testing.T) { 27 | ssid := "test" 28 | wifi.CurrentStatus = wifi.StatusIdle 29 | wifi.Begin(ssid) // StatusConnected 30 | wifi.Disconnect() // back to idle? 31 | assert.That("current status is idle", t, wifi.CurrentStatus, wifi.StatusIdle) 32 | } 33 | 34 | func TestWifiRSSIShouldBeNotMinusOne(t *testing.T) { 35 | ssid := "test" 36 | wifi.CurrentRSSI = -1 37 | wifi.Begin(ssid) 38 | assert.That("RSSI is set to 0", t, wifi.RSSI(), 0) 39 | } 40 | func TestWifiSSIDShouldNotBeEmpty(t *testing.T) { 41 | ssid := "test" 42 | wifi.CurrentSSID = "" 43 | wifi.Begin(ssid) 44 | assert.That("SSID is set to test", t, wifi.SSID(), "test") 45 | } 46 | --------------------------------------------------------------------------------