diff --git a/Examples/SwiftIOPlayground/11MoreProjects/MorseCode/.gitignore b/Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/.gitignore similarity index 100% rename from Examples/SwiftIOPlayground/11MoreProjects/MorseCode/.gitignore rename to Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/.gitignore diff --git a/Examples/SwiftIOPlayground/11MoreProjects/MorseCode/Package.mmp b/Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/Package.mmp similarity index 100% rename from Examples/SwiftIOPlayground/11MoreProjects/MorseCode/Package.mmp rename to Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/Package.mmp diff --git a/Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/Package.swift b/Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/Package.swift new file mode 100644 index 0000000..5c228cd --- /dev/null +++ b/Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/Package.swift @@ -0,0 +1,26 @@ +// swift-tools-version: 5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "JoiningWiFi", + dependencies: [ + // Dependencies declare other packages that this package depends on. + .package(url: "https://github.com/madmachineio/SwiftIO.git", branch: "main"), + .package(url: "https://github.com/madmachineio/MadBoards.git", branch: "main"), + .package(url: "https://github.com/madmachineio/MadDrivers.git", branch: "main"), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .executableTarget( + name: "JoiningWiFi", + dependencies: [ + "SwiftIO", + "MadBoards", + // Use specific library name rather than "MadDrivers" would speed up the build procedure. + .product(name: "ESP32ATClient", package: "MadDrivers") + ]), + ] +) diff --git a/Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/Sources/main.swift b/Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/Sources/main.swift new file mode 100644 index 0000000..b3b26b3 --- /dev/null +++ b/Examples/SwiftIOPlayground/11WiFi/JoiningWiFi/Sources/main.swift @@ -0,0 +1,33 @@ +import SwiftIO +import MadBoard +import ESP32ATClient + +let rst = DigitalOut(Id.D24, value: true) +let uart = UART(Id.UART1, baudRate: 115200) +let esp = ESP32ATClient(uart: uart, rst: rst) + +do { + // If reset failed, you might need to adjust the baudrate. + try esp.reset() + print("ESP32 status: \(esp.esp32Status)") + + // Only in 'Station' or 'Station+SoftAP' mode can a connection to an AP be established. + var wifiMode = ESP32ATClient.WiFiMode.station + _ = try esp.setWiFiMode(wifiMode) + + wifiMode = try esp.getWiFiMode() + print("ESP32 WiFi mode: \(wifiMode)") + + // Fill the SSID and password below. + try esp.joinAP(ssid: "TP-LINK_CD1C", password: "q1w2e3r4", timeout: 20000) + print("ESP32 WiFi status: \(esp.wifiStatus)") + + let ipInfo = try esp.getStationIP() + print(ipInfo) +} catch { + print("Error: \(error)") +} + +while true { + sleep(ms: 1000) +} \ No newline at end of file diff --git a/Examples/SwiftIOPlayground/11MoreProjects/MovingBall/.gitignore b/Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/.gitignore similarity index 100% rename from Examples/SwiftIOPlayground/11MoreProjects/MovingBall/.gitignore rename to Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/.gitignore diff --git a/Examples/SwiftIOPlayground/11MoreProjects/MovingBall/Package.mmp b/Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/Package.mmp similarity index 100% rename from Examples/SwiftIOPlayground/11MoreProjects/MovingBall/Package.mmp rename to Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/Package.mmp diff --git a/Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/Package.swift b/Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/Package.swift new file mode 100644 index 0000000..cb495af --- /dev/null +++ b/Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/Package.swift @@ -0,0 +1,27 @@ +// swift-tools-version: 5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "TemperatureDataLogger", + dependencies: [ + // Dependencies declare other packages that this package depends on. + .package(url: "https://github.com/madmachineio/SwiftIO.git", branch: "main"), + .package(url: "https://github.com/madmachineio/MadBoards.git", branch: "main"), + // .package(url: "https://github.com/madmachineio/MadDrivers.git", branch: "main"), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .executableTarget( + name: "TemperatureDataLogger", + dependencies: [ + "SwiftIO", + "MadBoards", + // Use specific library name rather than "MadDrivers" would speed up the build procedure. + .product(name: "ESP32ATClient", package: "MadDrivers"), + .product(name: "SHT3x", package: "MadDrivers"), + ]), + ] +) diff --git a/Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/Sources/main.swift b/Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/Sources/main.swift new file mode 100644 index 0000000..d8a2aa6 --- /dev/null +++ b/Examples/SwiftIOPlayground/11WiFi/TemperatureDataLogger/Sources/main.swift @@ -0,0 +1,51 @@ +import SwiftIO +import MadBoard +import ESP32ATClient +import SHT3x + +let rst = DigitalOut(Id.D24, value: true) +let uart = UART(Id.UART1, baudRate: 115200) +let esp = ESP32ATClient(uart: uart, rst: rst) + +let i2c = I2C(Id.I2C0) +let humiture = SHT3x(i2c) + +do { + // If reset failed, you might need to adjust the baudrate. + try esp.reset() + print("ESP32 status: \(esp.esp32Status)") + + // Only in 'Station' or 'Station+SoftAP' mode can a connection to an AP be established. + var wifiMode = ESP32ATClient.WiFiMode.station + _ = try esp.setWiFiMode(wifiMode) + + wifiMode = try esp.getWiFiMode() + print("ESP32 WiFi mode: \(wifiMode)") + + // Fill the SSID and password below. + try esp.joinAP(ssid: "TP-LINK_CD1C", password: "q1w2e3r4", timeout: 20000) + print("ESP32 WiFi status: \(esp.wifiStatus)") + + let ipInfo = try esp.getStationIP() + print(ipInfo) +} catch { + print("Error: \(error)") +} + +while true { + sleep(ms: 30_000) + if esp.wifiStatus == .ready { + do { + // Read temperature and humidity values from the sensor. + let temp = humiture.readCelsius() + let humidity = humiture.readHumidity() + // Send the values to ThingSpeak using HTTP POST requests to visualize them. + _ = try esp.httpPost(url: "https://api.thingspeak.com/update?api_key=WCGQWXCBJA2WS03F&field1=\(temp)&field2=\(humidity)", headers: ["Content-Type: application/x-www-form-urlencoded"], timeout: 20000) + } catch { + print("Http POST Error: \(error)") + } + } else { + _ = try? esp.readLine(timeout: 1000) + print("WiFi status: \(esp.wifiStatus)") + } +} \ No newline at end of file diff --git a/Examples/SwiftIOPlayground/11MoreProjects/Pong/.gitignore b/Examples/SwiftIOPlayground/11WiFi/Weather/.gitignore similarity index 100% rename from Examples/SwiftIOPlayground/11MoreProjects/Pong/.gitignore rename to Examples/SwiftIOPlayground/11WiFi/Weather/.gitignore diff --git a/Examples/SwiftIOPlayground/11MoreProjects/Pong/Package.mmp b/Examples/SwiftIOPlayground/11WiFi/Weather/Package.mmp similarity index 100% rename from Examples/SwiftIOPlayground/11MoreProjects/Pong/Package.mmp rename to Examples/SwiftIOPlayground/11WiFi/Weather/Package.mmp diff --git a/Examples/SwiftIOPlayground/11WiFi/Weather/Package.swift b/Examples/SwiftIOPlayground/11WiFi/Weather/Package.swift new file mode 100644 index 0000000..60f08a2 --- /dev/null +++ b/Examples/SwiftIOPlayground/11WiFi/Weather/Package.swift @@ -0,0 +1,28 @@ +// swift-tools-version: 5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "Weather", + dependencies: [ + // Dependencies declare other packages that this package depends on. + .package(url: "https://github.com/madmachineio/SwiftIO.git", branch: "main"), + .package(url: "https://github.com/madmachineio/MadBoards.git", branch: "main"), + .package(url: "https://github.com/madmachineio/MadDrivers.git", branch: "main"), + .package(url: "https://github.com/swift-extras/swift-extras-json.git", branch: "main"), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .executableTarget( + name: "Weather", + dependencies: [ + "SwiftIO", + "MadBoards", + // Use specific library name rather than "MadDrivers" would speed up the build procedure. + .product(name: "ESP32ATClient", package: "MadDrivers"), + .product(name: "ExtrasJSON", package: "swift-extras-json"), + ]), + ] +) diff --git a/Examples/SwiftIOPlayground/11WiFi/Weather/Sources/WeatherInfo.swift b/Examples/SwiftIOPlayground/11WiFi/Weather/Sources/WeatherInfo.swift new file mode 100644 index 0000000..9d4c498 --- /dev/null +++ b/Examples/SwiftIOPlayground/11WiFi/Weather/Sources/WeatherInfo.swift @@ -0,0 +1,124 @@ +// Structs used to decode the JSON data from the weather service. +struct Coordinate: Decodable { + let longitude: Float + let latitude: Float + + enum CodingKeys: String, CodingKey { + case longitude = "lon" + case latitude = "lat" + } +} + +struct WeatherConditions: Decodable { + let id: Int + let main: String + let description: String + let icon: String +} + +struct MainInfo: Decodable { + let temp: Float + let feelsLikeTemp: Float + let minTemp: Float + let maxTemp: Float + let pressure: Int + let humidity: Int + let seaLevel: Int + let groundLevel: Int + + enum CodingKeys: String, CodingKey { + case temp + case feelsLikeTemp = "feels_like" + case minTemp = "temp_min" + case maxTemp = "temp_max" + case pressure + case humidity + case seaLevel = "sea_level" + case groundLevel = "grnd_level" + } +} + +struct Wind: Decodable { + let speed: Float + let degree: Int + let gust: Float + + enum CodingKeys: String, CodingKey { + case speed + case degree = "deg" + case gust + } +} + +struct Clouds: Decodable { + let cloudiness: Int + + enum CodingKeys: String, CodingKey { + case cloudiness = "all" + } +} + +struct Rain: Decodable { + let rain1h: Float? + let rain3h: Float? + + enum CodingKeys: String, CodingKey { + case rain1h = "1h" + case rain3h = "3h" + } +} + +struct Snow: Decodable { + let snow1h: Float? + let snow3h: Float? + + enum CodingKeys: String, CodingKey { + case snow1h = "1h" + case snow3h = "3h" + } +} + +struct Sys: Decodable { + let type: Int? + let id: Int? + let country: String + let sunrise: Int + let sunset: Int +} + +struct WeatherInfo: Decodable { + let coordinate: Coordinate + let weatherConditions: [WeatherConditions] + let base: String + let mainInfo: MainInfo + let visibility: Int + let wind: Wind + let clouds: Clouds + let rain: Rain? + let snow: Snow? + let dt: Int + let sys: Sys + let timezone: Float + let cityId: Int + let cityName: String + let cod: Int + + + enum CodingKeys: String, CodingKey { + case coordinate = "coord" + case weatherConditions = "weather" + case base + case mainInfo = "main" + case visibility + case wind + case clouds + case rain + case snow + case dt + case sys + case timezone + case cityId = "id" + case cityName = "name" + case cod + } +} \ No newline at end of file diff --git a/Examples/SwiftIOPlayground/11WiFi/Weather/Sources/main.swift b/Examples/SwiftIOPlayground/11WiFi/Weather/Sources/main.swift new file mode 100644 index 0000000..05db4e6 --- /dev/null +++ b/Examples/SwiftIOPlayground/11WiFi/Weather/Sources/main.swift @@ -0,0 +1,60 @@ +import SwiftIO +import MadBoard +import ESP32ATClient +import ExtrasJSON + +let rst = DigitalOut(Id.D24, value: true) +let uart = UART(Id.UART1, baudRate: 115200) +let esp = ESP32ATClient(uart: uart, rst: rst) + +do { + // If reset failed, you might need to adjust the baudrate. + try esp.reset() + print("ESP32 status: \(esp.esp32Status)") + + // Only in 'Station' or 'Station+SoftAP' mode can a connection to an AP be established. + var wifiMode = ESP32ATClient.WiFiMode.station + _ = try esp.setWiFiMode(wifiMode) + + // Print current Wi-Fi mode. + wifiMode = try esp.getWiFiMode() + print("ESP32 WiFi mode: \(wifiMode)") + + // Fill the SSID and password below. + try esp.joinAP(ssid: "", password: "", timeout: 20000) + print("ESP32 WiFi status: \(esp.wifiStatus)") + + // Print the assigned IP address. + let ipInfo = try esp.getStationIP() + print(ipInfo) +} catch { + print("Error: \(error)") +} + +sleep(ms: 1000) + +if esp.wifiStatus == .ready { + do { + // Send request to the weather service to obtain current weather. + // Update the URL with your API key and your city name. + let response = try esp.httpGet(url: "https://api.openweathermap.org/data/2.5/weather?q=metric&q=YourCity&appid=YourAPIKey", timeout: 30000) + + // Decode the JSON data and print the weather info. + let weatherInfo = try XJSONDecoder().decode(WeatherInfo.self, from: Array(response.utf8)) + print("City: \(weatherInfo.cityName)") + print("Weather: \(weatherInfo.weatherConditions[0].main)") + print("Temp: \(weatherInfo.mainInfo.temp)C") + print("Humidity: \(weatherInfo.mainInfo.humidity)") + } catch let error as DecodingError { + print("JSON Decoding Error: \(error)") + } catch { + print("Http GET Error: \(error)") + } +} else { + _ = try? esp.readLine(timeout: 1000) + print("WiFi status: \(esp.wifiStatus)") +} + +while true { + sleep(ms: 1000) +} \ No newline at end of file diff --git a/Examples/SwiftIOPlayground/11MoreProjects/TicTacToe/.gitignore b/Examples/SwiftIOPlayground/12MoreProjects/LifeGame/.gitignore similarity index 100% rename from Examples/SwiftIOPlayground/11MoreProjects/TicTacToe/.gitignore rename to Examples/SwiftIOPlayground/12MoreProjects/LifeGame/.gitignore diff --git a/Examples/SwiftIOPlayground/11MoreProjects/TicTacToe/Package.mmp b/Examples/SwiftIOPlayground/12MoreProjects/LifeGame/Package.mmp similarity index 100% rename from Examples/SwiftIOPlayground/11MoreProjects/TicTacToe/Package.mmp rename to Examples/SwiftIOPlayground/12MoreProjects/LifeGame/Package.mmp diff --git a/Examples/SwiftIOPlayground/12MoreProjects/LifeGame/Package.swift b/Examples/SwiftIOPlayground/12MoreProjects/LifeGame/Package.swift new file mode 100644 index 0000000..dddd828 --- /dev/null +++ b/Examples/SwiftIOPlayground/12MoreProjects/LifeGame/Package.swift @@ -0,0 +1,26 @@ +// swift-tools-version: 5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "LifeGame", + dependencies: [ + // Dependencies declare other packages that this package depends on. + .package(url: "https://github.com/madmachineio/SwiftIO.git", branch: "main"), + .package(url: "https://github.com/madmachineio/MadBoards.git", branch: "main"), + .package(url: "https://github.com/madmachineio/MadDrivers.git", branch: "main"), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .executableTarget( + name: "LifeGame", + dependencies: [ + "SwiftIO", + "MadBoards", + // Use specific library name rather than "MadDrivers" would speed up the build procedure. + .product(name: "ST7789", package: "MadDrivers") + ]), + ] +) diff --git a/Examples/SwiftIOPlayground/12MoreProjects/LifeGame/Sources/main.swift b/Examples/SwiftIOPlayground/12MoreProjects/LifeGame/Sources/main.swift new file mode 100644 index 0000000..0f5d05e --- /dev/null +++ b/Examples/SwiftIOPlayground/12MoreProjects/LifeGame/Sources/main.swift @@ -0,0 +1,85 @@ +import SwiftIO +import MadBoard +import ST7789 + +let spi = SPI(Id.SPI0, speed: 30_000_000) +let cs = DigitalOut(Id.D5) +let dc = DigitalOut(Id.D13) +let rst = DigitalOut(Id.D12) +let bl = DigitalOut(Id.D2) + +// Initialize the LCD using the pins above. Rotate the screen to keep the original at the upper left. +let screen = ST7789(spi: spi, cs: cs, dc: dc, rst: rst, bl: bl, rotation: .angle90) + +let gridSize = 3 + +let rowCount = screen.height / gridSize +let columnCount = screen.width / gridSize + +var lastStates = [[Int]](repeating: [Int](repeating: 0, count: columnCount), count: rowCount) +var states = lastStates +var screenBuffer = [UInt16](repeating: 0, count: screen.width * screen.height) + +for y in 0.. Int { + var count = 0 + for row in (y-1)...(y+1) { + for column in (x-1)...(x+1) { + if (row >= 0 && row < rowCount) && + (column >= 0 && column < columnCount) && + !(row == y && column == x) && + states[row][column] == 1 + { + count += 1 + } + } + } + + return count +} + +func updateScreen(_ states: [[Int]]) { + for row in 0..