Add GPIO keywords, buying guide, embedded templates, and update to BotDevice
- Add GPIO & IoT Keywords documentation (keywords-gpio.md) - GPIO MODE, SET, GET, PWM, SERVO - I2C SCAN, READ, WRITE - SPI OPEN, TRANSFER, CLOSE - Sensor keywords: READ TEMPERATURE, HUMIDITY, DISTANCE, MOTION, LIGHT - Display keywords: LCD INIT/PRINT/CLEAR, OLED INIT/PRINT/DRAW/CLEAR - Relay and buzzer control - Complete examples: doorbell, thermostat, light automation - Add Beginner's Buying Guide (13-devices/buying-guide.md) - What is an SBC explained for beginners - Recommended starter kits by budget - Sample shopping lists for projects - Where to buy by region - First-time setup guide - Common beginner mistakes - Add Embedded Device Templates (02-templates/template-embedded.md) - thermostat.bas - Smart thermostat with AI - doorbell.bas - Smart doorbell with notifications - light-control.bas - Voice-controlled lights - security.bas - Motion alarm system - plant-monitor.bas - Automatic plant watering - kiosk.bas - Information display - Add SVG architecture diagram (embedded-architecture.svg) - Update mobile.md to use BotDevice branding (renamed from BotOS) - Update SUMMARY.md with new sections
This commit is contained in:
parent
d3bc28fac6
commit
42f97de134
6 changed files with 1825 additions and 21 deletions
825
src/02-templates/template-embedded.md
Normal file
825
src/02-templates/template-embedded.md
Normal file
|
|
@ -0,0 +1,825 @@
|
||||||
|
# Template: Embedded Devices
|
||||||
|
|
||||||
|
Ready-to-use templates for home automation, IoT projects, and embedded displays. Copy these templates to your `.gbdialog` folder and customize.
|
||||||
|
|
||||||
|
## Template Categories
|
||||||
|
|
||||||
|
| Template | Use Case | Hardware |
|
||||||
|
|----------|----------|----------|
|
||||||
|
| **thermostat.bas** | Smart thermostat | DHT22, Relay, OLED |
|
||||||
|
| **doorbell.bas** | Smart doorbell | Button, Camera, Buzzer |
|
||||||
|
| **light-control.bas** | Voice-controlled lights | Relay, Microphone |
|
||||||
|
| **security.bas** | Motion alarm | PIR, Buzzer, Camera |
|
||||||
|
| **plant-monitor.bas** | Plant watering | Soil sensor, Pump |
|
||||||
|
| **kiosk.bas** | Information display | HDMI display |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## thermostat.bas
|
||||||
|
|
||||||
|
Smart thermostat with scheduling and remote control.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' ============================================================
|
||||||
|
' SMART THERMOSTAT - Temperature control with AI assistant
|
||||||
|
' Hardware: DHT22 (GPIO 4), Relay (GPIO 17), OLED (I2C 0x3C)
|
||||||
|
' ============================================================
|
||||||
|
|
||||||
|
' Configuration
|
||||||
|
targetTemp = 22 ' Target temperature in Celsius
|
||||||
|
hysteresis = 0.5 ' Prevent rapid on/off cycling
|
||||||
|
heatingPin = 17
|
||||||
|
sensorPin = 4
|
||||||
|
|
||||||
|
' Initialize hardware
|
||||||
|
GPIO MODE heatingPin, "OUTPUT"
|
||||||
|
OLED INIT 0x3C, 128, 64
|
||||||
|
|
||||||
|
' Load saved settings
|
||||||
|
savedTarget = GET BOT MEMORY "thermostat_target"
|
||||||
|
IF savedTarget <> "" THEN
|
||||||
|
targetTemp = VAL(savedTarget)
|
||||||
|
END IF
|
||||||
|
|
||||||
|
TALK "Thermostat ready. Target: " + targetTemp + "°C"
|
||||||
|
|
||||||
|
' Main control loop
|
||||||
|
mainLoop:
|
||||||
|
' Read current temperature
|
||||||
|
currentTemp = READ TEMPERATURE sensorPin
|
||||||
|
humidity = READ HUMIDITY sensorPin
|
||||||
|
|
||||||
|
' Control logic with hysteresis
|
||||||
|
IF currentTemp < (targetTemp - hysteresis) THEN
|
||||||
|
GPIO SET heatingPin, HIGH
|
||||||
|
heating = "ON"
|
||||||
|
ELSEIF currentTemp > (targetTemp + hysteresis) THEN
|
||||||
|
GPIO SET heatingPin, LOW
|
||||||
|
heating = "OFF"
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Update display
|
||||||
|
OLED CLEAR
|
||||||
|
OLED PRINT 0, 0, "Current:", 1
|
||||||
|
OLED PRINT 0, 12, currentTemp + " C", 2
|
||||||
|
OLED PRINT 0, 35, "Target: " + targetTemp + " C", 1
|
||||||
|
OLED PRINT 0, 48, "Heat: " + heating, 1
|
||||||
|
OLED PRINT 80, 48, humidity + "%", 1
|
||||||
|
|
||||||
|
' Log to database every 5 minutes
|
||||||
|
IF MINUTE(NOW) MOD 5 = 0 AND SECOND(NOW) < 5 THEN
|
||||||
|
INSERT "temperature_log", {
|
||||||
|
"timestamp": NOW,
|
||||||
|
"temperature": currentTemp,
|
||||||
|
"humidity": humidity,
|
||||||
|
"heating": heating
|
||||||
|
}
|
||||||
|
END IF
|
||||||
|
|
||||||
|
WAIT 5
|
||||||
|
GOTO mainLoop
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
' Voice command handler (called when user speaks)
|
||||||
|
' ============================================================
|
||||||
|
SUB handleCommand(command)
|
||||||
|
' Use LLM to understand intent
|
||||||
|
intent = LLM "Parse thermostat command: '" + command + "'. Return JSON: {action: set/status/schedule, temperature: number or null}"
|
||||||
|
intent = JSON PARSE intent
|
||||||
|
|
||||||
|
SELECT CASE intent.action
|
||||||
|
CASE "set"
|
||||||
|
targetTemp = intent.temperature
|
||||||
|
SET BOT MEMORY "thermostat_target", targetTemp
|
||||||
|
TALK "Temperature set to " + targetTemp + " degrees"
|
||||||
|
|
||||||
|
CASE "status"
|
||||||
|
TALK "Current temperature is " + currentTemp + " degrees. Target is " + targetTemp + ". Heating is " + heating
|
||||||
|
|
||||||
|
CASE "schedule"
|
||||||
|
TALK "Scheduling not yet implemented"
|
||||||
|
END SELECT
|
||||||
|
END SUB
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## doorbell.bas
|
||||||
|
|
||||||
|
Smart doorbell with photo capture and notifications.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' ============================================================
|
||||||
|
' SMART DOORBELL - Ring detection with photo and notification
|
||||||
|
' Hardware: Button (GPIO 27), Buzzer (GPIO 18), LED (GPIO 17)
|
||||||
|
' Optional: Camera module, OLED display
|
||||||
|
' ============================================================
|
||||||
|
|
||||||
|
' Pin configuration
|
||||||
|
buttonPin = 27
|
||||||
|
buzzerPin = 18
|
||||||
|
ledPin = 17
|
||||||
|
|
||||||
|
' Setup
|
||||||
|
GPIO MODE buttonPin, "INPUT_PULLUP"
|
||||||
|
GPIO MODE buzzerPin, "OUTPUT"
|
||||||
|
GPIO MODE ledPin, "OUTPUT"
|
||||||
|
|
||||||
|
' Notification settings
|
||||||
|
ownerEmail = GET BOT MEMORY "doorbell_email"
|
||||||
|
IF ownerEmail = "" THEN
|
||||||
|
ownerEmail = "owner@example.com"
|
||||||
|
END IF
|
||||||
|
|
||||||
|
TALK "Doorbell system ready"
|
||||||
|
|
||||||
|
' Visual indicator that system is active
|
||||||
|
GPIO SET ledPin, LOW
|
||||||
|
|
||||||
|
mainLoop:
|
||||||
|
' Check button
|
||||||
|
IF GPIO GET buttonPin = LOW THEN
|
||||||
|
' Debounce
|
||||||
|
WAIT 0.05
|
||||||
|
IF GPIO GET buttonPin = LOW THEN
|
||||||
|
handleRing()
|
||||||
|
' Wait for button release
|
||||||
|
WHILE GPIO GET buttonPin = LOW
|
||||||
|
WAIT 0.01
|
||||||
|
WEND
|
||||||
|
END IF
|
||||||
|
END IF
|
||||||
|
|
||||||
|
WAIT 0.1
|
||||||
|
GOTO mainLoop
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
SUB handleRing()
|
||||||
|
timestamp = FORMAT(NOW, "HH:mm:ss")
|
||||||
|
|
||||||
|
' Visual and audio feedback
|
||||||
|
GPIO SET ledPin, HIGH
|
||||||
|
BUZZER buzzerPin, 1000, 0.3
|
||||||
|
WAIT 0.1
|
||||||
|
BUZZER buzzerPin, 1500, 0.3
|
||||||
|
|
||||||
|
' Try to capture photo
|
||||||
|
ON ERROR RESUME NEXT
|
||||||
|
photo = CAPTURE PHOTO
|
||||||
|
photoPath = "doorbell_" + FORMAT(NOW, "YYYYMMDD_HHmmss") + ".jpg"
|
||||||
|
IF NOT ERROR THEN
|
||||||
|
WRITE "photos/" + photoPath, photo
|
||||||
|
END IF
|
||||||
|
ON ERROR GOTO 0
|
||||||
|
|
||||||
|
' Log the ring
|
||||||
|
INSERT "doorbell_log", {
|
||||||
|
"timestamp": NOW,
|
||||||
|
"photo": photoPath
|
||||||
|
}
|
||||||
|
|
||||||
|
' Send notification
|
||||||
|
IF photo THEN
|
||||||
|
SEND MAIL ownerEmail, "Doorbell Ring", "Someone is at the door! Time: " + timestamp, [photo]
|
||||||
|
ELSE
|
||||||
|
SEND MAIL ownerEmail, "Doorbell Ring", "Someone is at the door! Time: " + timestamp
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Announce locally
|
||||||
|
TALK "Visitor at the door"
|
||||||
|
|
||||||
|
' LED off after 2 seconds
|
||||||
|
WAIT 2
|
||||||
|
GPIO SET ledPin, LOW
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
' Configuration command
|
||||||
|
' ============================================================
|
||||||
|
SUB setEmail(email)
|
||||||
|
SET BOT MEMORY "doorbell_email", email
|
||||||
|
ownerEmail = email
|
||||||
|
TALK "Notification email set to " + email
|
||||||
|
END SUB
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## light-control.bas
|
||||||
|
|
||||||
|
Voice-controlled lighting with scenes and schedules.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' ============================================================
|
||||||
|
' SMART LIGHTS - Voice and schedule controlled lighting
|
||||||
|
' Hardware: 4-channel relay on GPIO 17, 18, 27, 22
|
||||||
|
' ============================================================
|
||||||
|
|
||||||
|
' Room configuration
|
||||||
|
DIM rooms(4)
|
||||||
|
rooms(0) = "living room"
|
||||||
|
rooms(1) = "bedroom"
|
||||||
|
rooms(2) = "kitchen"
|
||||||
|
rooms(3) = "bathroom"
|
||||||
|
|
||||||
|
DIM pins(4)
|
||||||
|
pins(0) = 17
|
||||||
|
pins(1) = 18
|
||||||
|
pins(2) = 27
|
||||||
|
pins(3) = 22
|
||||||
|
|
||||||
|
' Initialize all relays
|
||||||
|
FOR i = 0 TO 3
|
||||||
|
GPIO MODE pins(i), "OUTPUT"
|
||||||
|
GPIO SET pins(i), LOW ' All lights off
|
||||||
|
NEXT
|
||||||
|
|
||||||
|
TALK "Light control ready. Say 'turn on' or 'turn off' followed by room name."
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
' Main dialog loop
|
||||||
|
' ============================================================
|
||||||
|
mainLoop:
|
||||||
|
command = HEAR
|
||||||
|
|
||||||
|
IF command <> "" THEN
|
||||||
|
handleCommand(command)
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Check schedules
|
||||||
|
checkSchedules()
|
||||||
|
|
||||||
|
WAIT 0.5
|
||||||
|
GOTO mainLoop
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
SUB handleCommand(command)
|
||||||
|
' Use LLM to parse command
|
||||||
|
prompt = "Parse light command: '" + command + "'. "
|
||||||
|
prompt = prompt + "Rooms: living room, bedroom, kitchen, bathroom, all. "
|
||||||
|
prompt = prompt + "Return JSON: {action: on/off/toggle/status/scene, room: string, scene: string or null}"
|
||||||
|
|
||||||
|
intent = LLM prompt
|
||||||
|
intent = JSON PARSE intent
|
||||||
|
|
||||||
|
SELECT CASE intent.action
|
||||||
|
CASE "on"
|
||||||
|
turnOn(intent.room)
|
||||||
|
CASE "off"
|
||||||
|
turnOff(intent.room)
|
||||||
|
CASE "toggle"
|
||||||
|
toggle(intent.room)
|
||||||
|
CASE "status"
|
||||||
|
reportStatus()
|
||||||
|
CASE "scene"
|
||||||
|
applyScene(intent.scene)
|
||||||
|
END SELECT
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
SUB turnOn(room)
|
||||||
|
IF room = "all" THEN
|
||||||
|
FOR i = 0 TO 3
|
||||||
|
RELAY SET pins(i), ON
|
||||||
|
NEXT
|
||||||
|
TALK "All lights on"
|
||||||
|
ELSE
|
||||||
|
FOR i = 0 TO 3
|
||||||
|
IF rooms(i) = room THEN
|
||||||
|
RELAY SET pins(i), ON
|
||||||
|
TALK room + " light on"
|
||||||
|
EXIT FOR
|
||||||
|
END IF
|
||||||
|
NEXT
|
||||||
|
END IF
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB turnOff(room)
|
||||||
|
IF room = "all" THEN
|
||||||
|
FOR i = 0 TO 3
|
||||||
|
RELAY SET pins(i), OFF
|
||||||
|
NEXT
|
||||||
|
TALK "All lights off"
|
||||||
|
ELSE
|
||||||
|
FOR i = 0 TO 3
|
||||||
|
IF rooms(i) = room THEN
|
||||||
|
RELAY SET pins(i), OFF
|
||||||
|
TALK room + " light off"
|
||||||
|
EXIT FOR
|
||||||
|
END IF
|
||||||
|
NEXT
|
||||||
|
END IF
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB toggle(room)
|
||||||
|
FOR i = 0 TO 3
|
||||||
|
IF rooms(i) = room OR room = "all" THEN
|
||||||
|
state = GPIO GET pins(i)
|
||||||
|
RELAY SET pins(i), NOT state
|
||||||
|
END IF
|
||||||
|
NEXT
|
||||||
|
TALK room + " toggled"
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB reportStatus()
|
||||||
|
status = "Light status: "
|
||||||
|
FOR i = 0 TO 3
|
||||||
|
state = GPIO GET pins(i)
|
||||||
|
IF state = HIGH THEN
|
||||||
|
status = status + rooms(i) + " ON, "
|
||||||
|
ELSE
|
||||||
|
status = status + rooms(i) + " off, "
|
||||||
|
END IF
|
||||||
|
NEXT
|
||||||
|
TALK status
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
' Scenes
|
||||||
|
' ============================================================
|
||||||
|
SUB applyScene(scene)
|
||||||
|
SELECT CASE scene
|
||||||
|
CASE "movie"
|
||||||
|
RELAY SET pins(0), OFF ' Living room dim
|
||||||
|
RELAY SET pins(1), OFF
|
||||||
|
RELAY SET pins(2), OFF
|
||||||
|
RELAY SET pins(3), OFF
|
||||||
|
TALK "Movie scene applied - all lights off"
|
||||||
|
|
||||||
|
CASE "morning"
|
||||||
|
RELAY SET pins(2), ON ' Kitchen on
|
||||||
|
RELAY SET pins(3), ON ' Bathroom on
|
||||||
|
RELAY SET pins(0), OFF
|
||||||
|
RELAY SET pins(1), OFF
|
||||||
|
TALK "Morning scene - kitchen and bathroom on"
|
||||||
|
|
||||||
|
CASE "night"
|
||||||
|
RELAY SET pins(1), ON ' Bedroom only
|
||||||
|
RELAY SET pins(0), OFF
|
||||||
|
RELAY SET pins(2), OFF
|
||||||
|
RELAY SET pins(3), OFF
|
||||||
|
TALK "Night scene - bedroom only"
|
||||||
|
|
||||||
|
CASE "all on"
|
||||||
|
FOR i = 0 TO 3
|
||||||
|
RELAY SET pins(i), ON
|
||||||
|
NEXT
|
||||||
|
TALK "All lights on"
|
||||||
|
END SELECT
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
' Schedule checking
|
||||||
|
' ============================================================
|
||||||
|
SUB checkSchedules()
|
||||||
|
hour = HOUR(NOW)
|
||||||
|
minute = MINUTE(NOW)
|
||||||
|
|
||||||
|
' Sunset - turn on living room
|
||||||
|
IF hour = 18 AND minute = 0 THEN
|
||||||
|
RELAY SET pins(0), ON
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Bedtime - night scene
|
||||||
|
IF hour = 22 AND minute = 30 THEN
|
||||||
|
applyScene("night")
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Late night - all off
|
||||||
|
IF hour = 23 AND minute = 30 THEN
|
||||||
|
turnOff("all")
|
||||||
|
END IF
|
||||||
|
END SUB
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## security.bas
|
||||||
|
|
||||||
|
Motion-activated security system with alerts.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' ============================================================
|
||||||
|
' SECURITY SYSTEM - Motion detection with alerts
|
||||||
|
' Hardware: PIR (GPIO 7), Buzzer (GPIO 18), LED (GPIO 17)
|
||||||
|
' Optional: Camera, OLED display
|
||||||
|
' ============================================================
|
||||||
|
|
||||||
|
' Configuration
|
||||||
|
pirPin = 7
|
||||||
|
buzzerPin = 18
|
||||||
|
ledPin = 17
|
||||||
|
alertEmail = "security@example.com"
|
||||||
|
|
||||||
|
' State
|
||||||
|
armed = FALSE
|
||||||
|
alertCooldown = 0
|
||||||
|
|
||||||
|
' Initialize
|
||||||
|
GPIO MODE pirPin, "INPUT"
|
||||||
|
GPIO MODE buzzerPin, "OUTPUT"
|
||||||
|
GPIO MODE ledPin, "OUTPUT"
|
||||||
|
|
||||||
|
TALK "Security system ready. Say 'arm' to activate."
|
||||||
|
|
||||||
|
mainLoop:
|
||||||
|
' Check for motion when armed
|
||||||
|
IF armed THEN
|
||||||
|
GPIO SET ledPin, HIGH ' Armed indicator
|
||||||
|
|
||||||
|
motion = READ MOTION pirPin
|
||||||
|
IF motion AND NOW > alertCooldown THEN
|
||||||
|
handleAlert()
|
||||||
|
alertCooldown = NOW + 60 ' 1 minute cooldown
|
||||||
|
END IF
|
||||||
|
ELSE
|
||||||
|
GPIO SET ledPin, LOW
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Check for commands
|
||||||
|
command = HEAR NOWAIT
|
||||||
|
IF command <> "" THEN
|
||||||
|
handleCommand(command)
|
||||||
|
END IF
|
||||||
|
|
||||||
|
WAIT 0.5
|
||||||
|
GOTO mainLoop
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
SUB handleCommand(command)
|
||||||
|
command = LOWER(command)
|
||||||
|
|
||||||
|
IF INSTR(command, "arm") > 0 THEN
|
||||||
|
IF INSTR(command, "disarm") > 0 THEN
|
||||||
|
disarmSystem()
|
||||||
|
ELSE
|
||||||
|
armSystem()
|
||||||
|
END IF
|
||||||
|
ELSEIF INSTR(command, "status") > 0 THEN
|
||||||
|
IF armed THEN
|
||||||
|
TALK "System is armed"
|
||||||
|
ELSE
|
||||||
|
TALK "System is disarmed"
|
||||||
|
END IF
|
||||||
|
ELSEIF INSTR(command, "test") > 0 THEN
|
||||||
|
testAlarm()
|
||||||
|
END IF
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB armSystem()
|
||||||
|
TALK "Arming in 10 seconds. Leave the area."
|
||||||
|
|
||||||
|
' Countdown beeps
|
||||||
|
FOR i = 10 TO 1 STEP -1
|
||||||
|
BUZZER buzzerPin, 1000, 0.1
|
||||||
|
WAIT 1
|
||||||
|
NEXT
|
||||||
|
|
||||||
|
armed = TRUE
|
||||||
|
BUZZER buzzerPin, 2000, 0.5
|
||||||
|
TALK "System armed"
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB disarmSystem()
|
||||||
|
armed = FALSE
|
||||||
|
GPIO SET ledPin, LOW
|
||||||
|
TALK "System disarmed"
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB handleAlert()
|
||||||
|
TALK "Motion detected! Alerting..."
|
||||||
|
|
||||||
|
' Sound alarm
|
||||||
|
FOR i = 1 TO 5
|
||||||
|
BUZZER buzzerPin, 2000, 0.2
|
||||||
|
WAIT 0.1
|
||||||
|
BUZZER buzzerPin, 1500, 0.2
|
||||||
|
WAIT 0.1
|
||||||
|
NEXT
|
||||||
|
|
||||||
|
' Capture photo if camera available
|
||||||
|
ON ERROR RESUME NEXT
|
||||||
|
photo = CAPTURE PHOTO
|
||||||
|
ON ERROR GOTO 0
|
||||||
|
|
||||||
|
' Log event
|
||||||
|
INSERT "security_events", {
|
||||||
|
"timestamp": NOW,
|
||||||
|
"type": "motion",
|
||||||
|
"photo": photo
|
||||||
|
}
|
||||||
|
|
||||||
|
' Send alert
|
||||||
|
IF photo THEN
|
||||||
|
SEND MAIL alertEmail, "SECURITY ALERT", "Motion detected at " + FORMAT(NOW, "HH:mm:ss"), [photo]
|
||||||
|
ELSE
|
||||||
|
SEND MAIL alertEmail, "SECURITY ALERT", "Motion detected at " + FORMAT(NOW, "HH:mm:ss")
|
||||||
|
END IF
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB testAlarm()
|
||||||
|
TALK "Testing alarm"
|
||||||
|
BUZZER buzzerPin, 1500, 0.5
|
||||||
|
WAIT 0.5
|
||||||
|
BUZZER buzzerPin, 2000, 0.5
|
||||||
|
TALK "Test complete"
|
||||||
|
END SUB
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## plant-monitor.bas
|
||||||
|
|
||||||
|
Automatic plant watering system.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' ============================================================
|
||||||
|
' PLANT MONITOR - Soil moisture monitoring and auto-watering
|
||||||
|
' Hardware: Soil sensor (ADC 0), Water pump relay (GPIO 17)
|
||||||
|
' Optional: DHT22 for air temp/humidity
|
||||||
|
' ============================================================
|
||||||
|
|
||||||
|
' Configuration
|
||||||
|
soilChannel = 0 ' ADC channel for soil sensor
|
||||||
|
pumpPin = 17 ' Relay for water pump
|
||||||
|
dryThreshold = 300 ' Below this = dry soil (adjust for your sensor)
|
||||||
|
wetThreshold = 700 ' Above this = wet enough
|
||||||
|
waterDuration = 5 ' Seconds to run pump
|
||||||
|
|
||||||
|
' Initialize
|
||||||
|
GPIO MODE pumpPin, "OUTPUT"
|
||||||
|
GPIO SET pumpPin, LOW
|
||||||
|
|
||||||
|
TALK "Plant monitor ready"
|
||||||
|
|
||||||
|
mainLoop:
|
||||||
|
' Read soil moisture
|
||||||
|
moisture = READ LIGHT soilChannel ' Using ADC reading
|
||||||
|
|
||||||
|
' Read air conditions if sensor available
|
||||||
|
ON ERROR RESUME NEXT
|
||||||
|
airTemp = READ TEMPERATURE 4
|
||||||
|
airHumidity = READ HUMIDITY 4
|
||||||
|
ON ERROR GOTO 0
|
||||||
|
|
||||||
|
' Determine soil status
|
||||||
|
IF moisture < dryThreshold THEN
|
||||||
|
status = "DRY"
|
||||||
|
needsWater = TRUE
|
||||||
|
ELSEIF moisture > wetThreshold THEN
|
||||||
|
status = "WET"
|
||||||
|
needsWater = FALSE
|
||||||
|
ELSE
|
||||||
|
status = "OK"
|
||||||
|
needsWater = FALSE
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Auto water if dry
|
||||||
|
IF needsWater THEN
|
||||||
|
waterPlant()
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Update display
|
||||||
|
LCD CLEAR
|
||||||
|
LCD PRINT 0, 0, "Soil: " + status
|
||||||
|
LCD PRINT 1, 0, "M:" + moisture
|
||||||
|
|
||||||
|
' Log every 30 minutes
|
||||||
|
IF MINUTE(NOW) MOD 30 = 0 AND SECOND(NOW) < 10 THEN
|
||||||
|
INSERT "plant_log", {
|
||||||
|
"timestamp": NOW,
|
||||||
|
"moisture": moisture,
|
||||||
|
"status": status,
|
||||||
|
"air_temp": airTemp,
|
||||||
|
"air_humidity": airHumidity
|
||||||
|
}
|
||||||
|
END IF
|
||||||
|
|
||||||
|
WAIT 60 ' Check every minute
|
||||||
|
GOTO mainLoop
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
SUB waterPlant()
|
||||||
|
' Only water during daytime (6am - 8pm)
|
||||||
|
hour = HOUR(NOW)
|
||||||
|
IF hour < 6 OR hour > 20 THEN
|
||||||
|
RETURN
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Check if we watered recently (within 2 hours)
|
||||||
|
lastWater = GET BOT MEMORY "last_water_time"
|
||||||
|
IF lastWater <> "" THEN
|
||||||
|
IF NOW - VAL(lastWater) < 7200 THEN ' 2 hours in seconds
|
||||||
|
RETURN
|
||||||
|
END IF
|
||||||
|
END IF
|
||||||
|
|
||||||
|
TALK "Watering plant"
|
||||||
|
|
||||||
|
' Run pump
|
||||||
|
GPIO SET pumpPin, HIGH
|
||||||
|
WAIT waterDuration
|
||||||
|
GPIO SET pumpPin, LOW
|
||||||
|
|
||||||
|
' Record watering
|
||||||
|
SET BOT MEMORY "last_water_time", NOW
|
||||||
|
|
||||||
|
INSERT "watering_log", {
|
||||||
|
"timestamp": NOW,
|
||||||
|
"duration": waterDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
' Send notification
|
||||||
|
SEND MAIL "gardener@example.com", "Plant Watered", "Your plant was automatically watered at " + FORMAT(NOW, "HH:mm")
|
||||||
|
|
||||||
|
TALK "Watering complete"
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
' Manual commands
|
||||||
|
' ============================================================
|
||||||
|
SUB handleCommand(command)
|
||||||
|
IF INSTR(command, "water") > 0 THEN
|
||||||
|
TALK "Manual watering"
|
||||||
|
GPIO SET pumpPin, HIGH
|
||||||
|
WAIT waterDuration
|
||||||
|
GPIO SET pumpPin, LOW
|
||||||
|
TALK "Done"
|
||||||
|
ELSEIF INSTR(command, "status") > 0 THEN
|
||||||
|
TALK "Soil moisture is " + moisture + ". Status: " + status
|
||||||
|
END IF
|
||||||
|
END SUB
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## kiosk.bas
|
||||||
|
|
||||||
|
Information display kiosk for lobbies and public spaces.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' ============================================================
|
||||||
|
' INFO KIOSK - Public information display with AI assistant
|
||||||
|
' Hardware: HDMI display, touch screen or keyboard
|
||||||
|
' ============================================================
|
||||||
|
|
||||||
|
' Configuration
|
||||||
|
welcomeMessage = "Welcome! How can I help you today?"
|
||||||
|
idleTimeout = 60 ' Return to welcome screen after inactivity
|
||||||
|
|
||||||
|
' State
|
||||||
|
lastActivity = NOW
|
||||||
|
|
||||||
|
' Initialize display
|
||||||
|
' (Runs in browser kiosk mode at http://localhost:8088/embedded/)
|
||||||
|
|
||||||
|
TALK welcomeMessage
|
||||||
|
|
||||||
|
mainLoop:
|
||||||
|
' Check for user input
|
||||||
|
input = HEAR NOWAIT
|
||||||
|
|
||||||
|
IF input <> "" THEN
|
||||||
|
lastActivity = NOW
|
||||||
|
handleQuery(input)
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Return to welcome screen after idle
|
||||||
|
IF NOW - lastActivity > idleTimeout THEN
|
||||||
|
showWelcome()
|
||||||
|
lastActivity = NOW
|
||||||
|
END IF
|
||||||
|
|
||||||
|
WAIT 0.5
|
||||||
|
GOTO mainLoop
|
||||||
|
|
||||||
|
' ============================================================
|
||||||
|
SUB handleQuery(query)
|
||||||
|
' Log the query
|
||||||
|
INSERT "kiosk_queries", {
|
||||||
|
"timestamp": NOW,
|
||||||
|
"query": query
|
||||||
|
}
|
||||||
|
|
||||||
|
' Determine intent
|
||||||
|
intent = LLM "Classify query: '" + query + "'. Categories: directions, hours, services, general, weather. Return JSON: {category: string, details: string}"
|
||||||
|
intent = JSON PARSE intent
|
||||||
|
|
||||||
|
SELECT CASE intent.category
|
||||||
|
CASE "directions"
|
||||||
|
handleDirections(intent.details)
|
||||||
|
CASE "hours"
|
||||||
|
handleHours(intent.details)
|
||||||
|
CASE "services"
|
||||||
|
handleServices(intent.details)
|
||||||
|
CASE "weather"
|
||||||
|
handleWeather()
|
||||||
|
CASE ELSE
|
||||||
|
handleGeneral(query)
|
||||||
|
END SELECT
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB handleDirections(destination)
|
||||||
|
' Look up location in database
|
||||||
|
location = FIND "locations", "name LIKE '%" + destination + "%'"
|
||||||
|
|
||||||
|
IF location THEN
|
||||||
|
TALK "To get to " + location.name + ": " + location.directions
|
||||||
|
ELSE
|
||||||
|
TALK "I'm sorry, I don't have directions to " + destination + ". Please ask at the front desk."
|
||||||
|
END IF
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB handleHours(department)
|
||||||
|
hours = FIND "hours", "department LIKE '%" + department + "%'"
|
||||||
|
|
||||||
|
IF hours THEN
|
||||||
|
TALK hours.department + " is open " + hours.schedule
|
||||||
|
ELSE
|
||||||
|
TALK "Standard hours are Monday to Friday, 9 AM to 5 PM."
|
||||||
|
END IF
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB handleServices(service)
|
||||||
|
info = FIND "services", "name LIKE '%" + service + "%'"
|
||||||
|
|
||||||
|
IF info THEN
|
||||||
|
TALK info.description
|
||||||
|
ELSE
|
||||||
|
' Use KB for general info
|
||||||
|
USE KB "services"
|
||||||
|
answer = LLM "What services are available for: " + service
|
||||||
|
TALK answer
|
||||||
|
END IF
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB handleWeather()
|
||||||
|
weather = WEATHER "local"
|
||||||
|
TALK "Current weather: " + weather.description + ", " + weather.temperature + " degrees."
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB handleGeneral(query)
|
||||||
|
' Use KB for general questions
|
||||||
|
USE KB "faq"
|
||||||
|
answer = LLM query
|
||||||
|
TALK answer
|
||||||
|
END SUB
|
||||||
|
|
||||||
|
SUB showWelcome()
|
||||||
|
TALK welcomeMessage
|
||||||
|
END SUB
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Installing Templates
|
||||||
|
|
||||||
|
1. Create a `.gbdialog` folder in your bot package:
|
||||||
|
```bash
|
||||||
|
mkdir -p mybot.gbai/mybot.gbdialog
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Copy the desired template:
|
||||||
|
```bash
|
||||||
|
cp template-embedded.md mybot.gbai/mybot.gbdialog/thermostat.bas
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Edit configuration at the top of the file
|
||||||
|
|
||||||
|
4. Deploy to your device:
|
||||||
|
```bash
|
||||||
|
./scripts/deploy-embedded.sh pi@mydevice --with-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customizing
|
||||||
|
|
||||||
|
Each template has a configuration section at the top:
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Configuration
|
||||||
|
targetTemp = 22 ' Target temperature in Celsius
|
||||||
|
heatingPin = 17 ' GPIO pin for relay
|
||||||
|
sensorPin = 4 ' GPIO pin for sensor
|
||||||
|
```
|
||||||
|
|
||||||
|
Modify these values to match your hardware setup.
|
||||||
|
|
||||||
|
### Combining Templates
|
||||||
|
|
||||||
|
You can combine functionality from multiple templates into a single dialog:
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Combined home automation
|
||||||
|
INCLUDE "thermostat.bas"
|
||||||
|
INCLUDE "light-control.bas"
|
||||||
|
INCLUDE "security.bas"
|
||||||
|
|
||||||
|
' Main loop handles all systems
|
||||||
|
mainLoop:
|
||||||
|
checkThermostat()
|
||||||
|
checkLights()
|
||||||
|
checkSecurity()
|
||||||
|
WAIT 1
|
||||||
|
GOTO mainLoop
|
||||||
528
src/06-gbdialog/keywords-gpio.md
Normal file
528
src/06-gbdialog/keywords-gpio.md
Normal file
|
|
@ -0,0 +1,528 @@
|
||||||
|
# GPIO & IoT Keywords
|
||||||
|
|
||||||
|
Control hardware directly from BASIC dialogs. These keywords work on Raspberry Pi, Orange Pi, and other SBCs running botserver.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ GPIO Keyword Architecture │
|
||||||
|
├────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ BASIC Dialog botserver Hardware │
|
||||||
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||||
|
│ │ GPIO SET │────────▶│ sysfs/ │────────▶│ Pin │ │
|
||||||
|
│ │ GPIO GET │◀────────│ gpiod │◀────────│ State │ │
|
||||||
|
│ │ I2C READ │◀────────│ i2c-dev │◀────────│ Sensor │ │
|
||||||
|
│ │ SPI WRITE│────────▶│ spidev │────────▶│ Display │ │
|
||||||
|
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## GPIO Keywords
|
||||||
|
|
||||||
|
### GPIO MODE
|
||||||
|
|
||||||
|
Set a GPIO pin as input or output.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Set pin 17 as output (for LED, relay)
|
||||||
|
GPIO MODE 17, "OUTPUT"
|
||||||
|
|
||||||
|
' Set pin 27 as input (for button, sensor)
|
||||||
|
GPIO MODE 27, "INPUT"
|
||||||
|
|
||||||
|
' Set input with pull-up resistor
|
||||||
|
GPIO MODE 27, "INPUT_PULLUP"
|
||||||
|
|
||||||
|
' Set input with pull-down resistor
|
||||||
|
GPIO MODE 22, "INPUT_PULLDOWN"
|
||||||
|
```
|
||||||
|
|
||||||
|
### GPIO SET
|
||||||
|
|
||||||
|
Set the state of an output pin.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Turn on LED (HIGH = 3.3V)
|
||||||
|
GPIO SET 17, HIGH
|
||||||
|
|
||||||
|
' Turn off LED (LOW = 0V)
|
||||||
|
GPIO SET 17, LOW
|
||||||
|
|
||||||
|
' Using numeric values (1 = HIGH, 0 = LOW)
|
||||||
|
GPIO SET 17, 1
|
||||||
|
GPIO SET 17, 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### GPIO GET
|
||||||
|
|
||||||
|
Read the state of an input pin.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Read button state
|
||||||
|
GPIO MODE 27, "INPUT_PULLUP"
|
||||||
|
state = GPIO GET 27
|
||||||
|
|
||||||
|
IF state = LOW THEN
|
||||||
|
TALK "Button pressed!"
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### GPIO PWM
|
||||||
|
|
||||||
|
Generate PWM signal for motor speed, LED brightness.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Set PWM on pin 18, duty cycle 0-100
|
||||||
|
GPIO PWM 18, 50 ' 50% duty cycle
|
||||||
|
|
||||||
|
' Fade LED
|
||||||
|
FOR brightness = 0 TO 100 STEP 5
|
||||||
|
GPIO PWM 18, brightness
|
||||||
|
WAIT 0.05
|
||||||
|
NEXT
|
||||||
|
|
||||||
|
' Stop PWM
|
||||||
|
GPIO PWM 18, 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### GPIO SERVO
|
||||||
|
|
||||||
|
Control servo motors (uses hardware PWM).
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Move servo to angle (0-180 degrees)
|
||||||
|
GPIO SERVO 12, 90 ' Center position
|
||||||
|
GPIO SERVO 12, 0 ' Left position
|
||||||
|
GPIO SERVO 12, 180 ' Right position
|
||||||
|
```
|
||||||
|
|
||||||
|
## I2C Keywords
|
||||||
|
|
||||||
|
For sensors and displays connected via I2C bus.
|
||||||
|
|
||||||
|
### I2C SCAN
|
||||||
|
|
||||||
|
Scan for connected I2C devices.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Scan I2C bus 1 (default on Pi)
|
||||||
|
devices = I2C SCAN 1
|
||||||
|
|
||||||
|
FOR EACH addr IN devices
|
||||||
|
TALK "Found device at address: " + HEX(addr)
|
||||||
|
NEXT
|
||||||
|
```
|
||||||
|
|
||||||
|
### I2C READ
|
||||||
|
|
||||||
|
Read data from an I2C device.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Read temperature from sensor at address 0x48
|
||||||
|
' Register 0x00 contains temperature
|
||||||
|
temp_raw = I2C READ 0x48, 0x00, 2 ' Read 2 bytes
|
||||||
|
|
||||||
|
' Convert to temperature
|
||||||
|
temperature = temp_raw / 256.0
|
||||||
|
TALK "Temperature: " + temperature + "°C"
|
||||||
|
```
|
||||||
|
|
||||||
|
### I2C WRITE
|
||||||
|
|
||||||
|
Write data to an I2C device.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Write configuration to sensor
|
||||||
|
I2C WRITE 0x48, 0x01, 0x60 ' Write 0x60 to register 0x01
|
||||||
|
|
||||||
|
' Write multiple bytes
|
||||||
|
I2C WRITE 0x3C, 0x00, [0xAE, 0xD5, 0x80] ' OLED init sequence
|
||||||
|
```
|
||||||
|
|
||||||
|
## SPI Keywords
|
||||||
|
|
||||||
|
For high-speed communication with displays and sensors.
|
||||||
|
|
||||||
|
### SPI OPEN
|
||||||
|
|
||||||
|
Open SPI device.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Open SPI device 0, chip select 0
|
||||||
|
SPI OPEN 0, 0, 1000000 ' 1MHz clock speed
|
||||||
|
```
|
||||||
|
|
||||||
|
### SPI TRANSFER
|
||||||
|
|
||||||
|
Send and receive data.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Send command to display
|
||||||
|
response = SPI TRANSFER [0x9F] ' Read ID command
|
||||||
|
|
||||||
|
' Send data to display
|
||||||
|
SPI TRANSFER [0x00, 0xFF, 0x00, 0xFF] ' Pattern data
|
||||||
|
```
|
||||||
|
|
||||||
|
### SPI CLOSE
|
||||||
|
|
||||||
|
Close SPI connection.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
SPI CLOSE 0, 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sensor Keywords
|
||||||
|
|
||||||
|
High-level keywords for common sensors.
|
||||||
|
|
||||||
|
### READ TEMPERATURE
|
||||||
|
|
||||||
|
Read temperature from common sensors (auto-detects DHT11, DHT22, DS18B20, BME280).
|
||||||
|
|
||||||
|
```bas
|
||||||
|
temp = READ TEMPERATURE 4 ' GPIO pin 4
|
||||||
|
TALK "Temperature: " + temp + "°C"
|
||||||
|
```
|
||||||
|
|
||||||
|
### READ HUMIDITY
|
||||||
|
|
||||||
|
Read humidity from DHT11/DHT22/BME280.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
humidity = READ HUMIDITY 4
|
||||||
|
TALK "Humidity: " + humidity + "%"
|
||||||
|
```
|
||||||
|
|
||||||
|
### READ DISTANCE
|
||||||
|
|
||||||
|
Read distance from ultrasonic sensor (HC-SR04).
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Trigger pin 23, Echo pin 24
|
||||||
|
distance = READ DISTANCE 23, 24
|
||||||
|
TALK "Distance: " + distance + " cm"
|
||||||
|
```
|
||||||
|
|
||||||
|
### READ MOTION
|
||||||
|
|
||||||
|
Read PIR motion sensor.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
GPIO MODE 7, "INPUT"
|
||||||
|
motion = READ MOTION 7
|
||||||
|
|
||||||
|
IF motion THEN
|
||||||
|
TALK "Motion detected!"
|
||||||
|
GPIO SET 17, HIGH ' Turn on light
|
||||||
|
END IF
|
||||||
|
```
|
||||||
|
|
||||||
|
### READ LIGHT
|
||||||
|
|
||||||
|
Read light level from photoresistor or light sensor.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
light = READ LIGHT 0 ' ADC channel 0 (MCP3008)
|
||||||
|
TALK "Light level: " + light
|
||||||
|
```
|
||||||
|
|
||||||
|
## Display Keywords
|
||||||
|
|
||||||
|
### LCD INIT
|
||||||
|
|
||||||
|
Initialize character LCD (HD44780).
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' I2C LCD at address 0x27, 16 columns, 2 rows
|
||||||
|
LCD INIT 0x27, 16, 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### LCD PRINT
|
||||||
|
|
||||||
|
Print text to LCD.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
LCD PRINT "Hello World!"
|
||||||
|
|
||||||
|
' Print at specific position (row, column)
|
||||||
|
LCD PRINT 0, 0, "Line 1"
|
||||||
|
LCD PRINT 1, 0, "Line 2"
|
||||||
|
```
|
||||||
|
|
||||||
|
### LCD CLEAR
|
||||||
|
|
||||||
|
Clear the LCD display.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
LCD CLEAR
|
||||||
|
```
|
||||||
|
|
||||||
|
### OLED INIT
|
||||||
|
|
||||||
|
Initialize OLED display (SSD1306).
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' I2C OLED at address 0x3C, 128x64 pixels
|
||||||
|
OLED INIT 0x3C, 128, 64
|
||||||
|
```
|
||||||
|
|
||||||
|
### OLED PRINT
|
||||||
|
|
||||||
|
Print text to OLED.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
OLED PRINT "Hello!"
|
||||||
|
|
||||||
|
' With position and size
|
||||||
|
OLED PRINT 0, 0, "Title", 2 ' Size 2x
|
||||||
|
OLED PRINT 0, 20, "Subtitle", 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### OLED DRAW
|
||||||
|
|
||||||
|
Draw shapes on OLED.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Draw rectangle
|
||||||
|
OLED DRAW "rect", 10, 10, 50, 30
|
||||||
|
|
||||||
|
' Draw circle
|
||||||
|
OLED DRAW "circle", 64, 32, 20
|
||||||
|
|
||||||
|
' Draw line
|
||||||
|
OLED DRAW "line", 0, 0, 127, 63
|
||||||
|
```
|
||||||
|
|
||||||
|
### OLED CLEAR
|
||||||
|
|
||||||
|
Clear the OLED display.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
OLED CLEAR
|
||||||
|
```
|
||||||
|
|
||||||
|
## Relay & Actuator Keywords
|
||||||
|
|
||||||
|
### RELAY SET
|
||||||
|
|
||||||
|
Control relay module.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Turn on relay 1 (pin 17)
|
||||||
|
RELAY SET 17, ON
|
||||||
|
|
||||||
|
' Turn off relay
|
||||||
|
RELAY SET 17, OFF
|
||||||
|
|
||||||
|
' Toggle relay
|
||||||
|
state = GPIO GET 17
|
||||||
|
RELAY SET 17, NOT state
|
||||||
|
```
|
||||||
|
|
||||||
|
### BUZZER
|
||||||
|
|
||||||
|
Control buzzer for alerts.
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Beep for 0.5 seconds
|
||||||
|
BUZZER 18, 0.5
|
||||||
|
|
||||||
|
' Play tone (frequency, duration)
|
||||||
|
BUZZER 18, 1000, 0.2 ' 1000Hz for 0.2 seconds
|
||||||
|
|
||||||
|
' Play melody
|
||||||
|
BUZZER 18, 262, 0.25 ' C4
|
||||||
|
BUZZER 18, 294, 0.25 ' D4
|
||||||
|
BUZZER 18, 330, 0.25 ' E4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complete Examples
|
||||||
|
|
||||||
|
### Smart Doorbell
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Smart doorbell with camera and notification
|
||||||
|
' Hardware: Button on GPIO 27, Buzzer on GPIO 18, LED on GPIO 17
|
||||||
|
|
||||||
|
GPIO MODE 27, "INPUT_PULLUP"
|
||||||
|
GPIO MODE 18, "OUTPUT"
|
||||||
|
GPIO MODE 17, "OUTPUT"
|
||||||
|
|
||||||
|
TALK "Doorbell system ready"
|
||||||
|
LCD PRINT "Ring the bell"
|
||||||
|
|
||||||
|
mainLoop:
|
||||||
|
button = GPIO GET 27
|
||||||
|
|
||||||
|
IF button = LOW THEN
|
||||||
|
' Button pressed
|
||||||
|
GPIO SET 17, HIGH ' LED on
|
||||||
|
BUZZER 18, 1000, 0.5 ' Ring buzzer
|
||||||
|
|
||||||
|
' Take photo (if camera connected)
|
||||||
|
photo = CAPTURE PHOTO
|
||||||
|
|
||||||
|
' Send notification
|
||||||
|
SEND MAIL "owner@home.com", "Doorbell", "Someone at the door!", photo
|
||||||
|
|
||||||
|
LCD PRINT "Visitor!"
|
||||||
|
WAIT 2
|
||||||
|
LCD PRINT "Ring the bell"
|
||||||
|
GPIO SET 17, LOW ' LED off
|
||||||
|
END IF
|
||||||
|
|
||||||
|
WAIT 0.1
|
||||||
|
GOTO mainLoop
|
||||||
|
```
|
||||||
|
|
||||||
|
### Temperature Monitor
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Temperature and humidity monitor with OLED display
|
||||||
|
' Hardware: DHT22 on GPIO 4, OLED on I2C 0x3C
|
||||||
|
|
||||||
|
OLED INIT 0x3C, 128, 64
|
||||||
|
|
||||||
|
mainLoop:
|
||||||
|
temp = READ TEMPERATURE 4
|
||||||
|
humidity = READ HUMIDITY 4
|
||||||
|
|
||||||
|
OLED CLEAR
|
||||||
|
OLED PRINT 0, 0, "Temperature:", 1
|
||||||
|
OLED PRINT 0, 15, temp + " C", 2
|
||||||
|
OLED PRINT 0, 40, "Humidity:", 1
|
||||||
|
OLED PRINT 0, 55, humidity + " %", 2
|
||||||
|
|
||||||
|
' Alert if too hot
|
||||||
|
IF temp > 30 THEN
|
||||||
|
BUZZER 18, 2000, 0.1
|
||||||
|
SEND MAIL "admin@home.com", "Alert", "Temperature high: " + temp + "C"
|
||||||
|
END IF
|
||||||
|
|
||||||
|
WAIT 5 ' Update every 5 seconds
|
||||||
|
GOTO mainLoop
|
||||||
|
```
|
||||||
|
|
||||||
|
### Light Automation
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Automatic light control based on motion and ambient light
|
||||||
|
' Hardware: PIR on GPIO 7, Light sensor on ADC0, Relay on GPIO 17
|
||||||
|
|
||||||
|
GPIO MODE 7, "INPUT"
|
||||||
|
GPIO MODE 17, "OUTPUT"
|
||||||
|
|
||||||
|
threshold = 500 ' Light threshold
|
||||||
|
timeout = 30 ' Seconds to keep light on
|
||||||
|
|
||||||
|
lastMotion = 0
|
||||||
|
|
||||||
|
mainLoop:
|
||||||
|
motion = READ MOTION 7
|
||||||
|
light = READ LIGHT 0
|
||||||
|
|
||||||
|
IF motion AND light < threshold THEN
|
||||||
|
' Dark and motion detected
|
||||||
|
RELAY SET 17, ON
|
||||||
|
lastMotion = NOW
|
||||||
|
LCD PRINT "Light ON"
|
||||||
|
END IF
|
||||||
|
|
||||||
|
' Turn off after timeout
|
||||||
|
IF NOW - lastMotion > timeout THEN
|
||||||
|
RELAY SET 17, OFF
|
||||||
|
LCD PRINT "Light OFF"
|
||||||
|
END IF
|
||||||
|
|
||||||
|
WAIT 0.5
|
||||||
|
GOTO mainLoop
|
||||||
|
```
|
||||||
|
|
||||||
|
### Voice-Controlled Lights
|
||||||
|
|
||||||
|
```bas
|
||||||
|
' Voice control for home automation
|
||||||
|
' Ask the AI to control lights
|
||||||
|
|
||||||
|
TALK "What would you like me to do?"
|
||||||
|
command = HEAR
|
||||||
|
|
||||||
|
' Use LLM to understand command
|
||||||
|
intent = LLM "Extract intent from: '" + command + "'. Return JSON: {action: on/off, room: string}"
|
||||||
|
intent = JSON PARSE intent
|
||||||
|
|
||||||
|
SELECT CASE intent.room
|
||||||
|
CASE "living room"
|
||||||
|
RELAY SET 17, intent.action = "on"
|
||||||
|
CASE "bedroom"
|
||||||
|
RELAY SET 18, intent.action = "on"
|
||||||
|
CASE "kitchen"
|
||||||
|
RELAY SET 27, intent.action = "on"
|
||||||
|
CASE "all"
|
||||||
|
RELAY SET 17, intent.action = "on"
|
||||||
|
RELAY SET 18, intent.action = "on"
|
||||||
|
RELAY SET 27, intent.action = "on"
|
||||||
|
END SELECT
|
||||||
|
|
||||||
|
TALK "Done! " + intent.room + " light is now " + intent.action
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pin Reference
|
||||||
|
|
||||||
|
### Raspberry Pi GPIO
|
||||||
|
|
||||||
|
| Pin | GPIO | Common Use |
|
||||||
|
|-----|------|------------|
|
||||||
|
| 11 | GPIO17 | Output (LED, Relay) |
|
||||||
|
| 12 | GPIO18 | PWM (Motor, Servo) |
|
||||||
|
| 13 | GPIO27 | Input (Button) |
|
||||||
|
| 15 | GPIO22 | Input/Output |
|
||||||
|
| 16 | GPIO23 | Input/Output |
|
||||||
|
| 18 | GPIO24 | Input/Output |
|
||||||
|
| 3 | SDA | I2C Data |
|
||||||
|
| 5 | SCL | I2C Clock |
|
||||||
|
| 19 | MOSI | SPI Data Out |
|
||||||
|
| 21 | MISO | SPI Data In |
|
||||||
|
| 23 | SCLK | SPI Clock |
|
||||||
|
|
||||||
|
### Orange Pi GPIO
|
||||||
|
|
||||||
|
Similar pinout, but check your specific model. Orange Pi 5 uses different GPIO numbering.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Permission Denied
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Add user to gpio group
|
||||||
|
sudo usermod -a -G gpio $USER
|
||||||
|
sudo usermod -a -G i2c $USER
|
||||||
|
sudo usermod -a -G spi $USER
|
||||||
|
|
||||||
|
# Or run botserver with elevated privileges
|
||||||
|
sudo systemctl edit botserver
|
||||||
|
# Add: User=root
|
||||||
|
```
|
||||||
|
|
||||||
|
### I2C Not Working
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable I2C
|
||||||
|
sudo raspi-config # Interface Options → I2C
|
||||||
|
|
||||||
|
# Check if device detected
|
||||||
|
i2cdetect -y 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### GPIO Busy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check what's using the GPIO
|
||||||
|
cat /sys/kernel/debug/gpio
|
||||||
|
|
||||||
|
# Release GPIO
|
||||||
|
echo 17 > /sys/class/gpio/unexport
|
||||||
324
src/13-devices/buying-guide.md
Normal file
324
src/13-devices/buying-guide.md
Normal file
|
|
@ -0,0 +1,324 @@
|
||||||
|
# Beginner's Guide: Buying Your First SBC
|
||||||
|
|
||||||
|
A complete guide for beginners who want to buy a Single Board Computer (SBC) and start automating their home or workplace with General Bots.
|
||||||
|
|
||||||
|
## What is an SBC?
|
||||||
|
|
||||||
|
A Single Board Computer (SBC) is a complete computer on a single circuit board. Unlike a desktop PC, it's:
|
||||||
|
|
||||||
|
- **Small** - Credit card to smartphone size
|
||||||
|
- **Low power** - 2-15 watts (vs 200W+ for a PC)
|
||||||
|
- **Affordable** - $15-150 depending on power
|
||||||
|
- **Quiet** - No fans on most models
|
||||||
|
- **GPIO equipped** - Can connect to sensors and actuators
|
||||||
|
|
||||||
|
## Which SBC Should I Buy?
|
||||||
|
|
||||||
|
### Decision Flowchart
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────┐
|
||||||
|
│ What's your budget? │
|
||||||
|
└───────────┬─────────────┘
|
||||||
|
│
|
||||||
|
┌───────────────────┼───────────────────┐
|
||||||
|
▼ ▼ ▼
|
||||||
|
Under $30 $30-80 $80-150
|
||||||
|
│ │ │
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||||
|
│ Orange Pi │ │ Raspberry Pi │ │ Orange Pi 5 │
|
||||||
|
│ Zero 3 │ │ 4 / 5 │ │ (with NPU) │
|
||||||
|
│ │ │ │ │ │
|
||||||
|
│ Basic display │ │ Full desktop │ │ Local AI/LLM │
|
||||||
|
│ Simple tasks │ │ Most projects │ │ Edge AI │
|
||||||
|
└───────────────┘ └───────────────┘ └───────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Recommended Starter Kits
|
||||||
|
|
||||||
|
#### 🌟 Best for Beginners: Raspberry Pi 4 Kit (~$80)
|
||||||
|
|
||||||
|
**What to buy:**
|
||||||
|
- Raspberry Pi 4 Model B (4GB RAM) - $55
|
||||||
|
- Official power supply (USB-C 5V 3A) - $8
|
||||||
|
- 32GB microSD card (Class 10) - $8
|
||||||
|
- Case with heatsink - $10
|
||||||
|
|
||||||
|
**Where to buy:**
|
||||||
|
- [The Pi Hut](https://thepihut.com) (UK)
|
||||||
|
- [Adafruit](https://adafruit.com) (US)
|
||||||
|
- [Amazon](https://amazon.com) (Worldwide)
|
||||||
|
- AliExpress (Budget option, slower shipping)
|
||||||
|
|
||||||
|
#### 💰 Budget Option: Orange Pi Zero 3 Kit (~$35)
|
||||||
|
|
||||||
|
**What to buy:**
|
||||||
|
- Orange Pi Zero 3 (1GB RAM) - $20
|
||||||
|
- 5V 2A power supply - $5
|
||||||
|
- 16GB microSD card - $5
|
||||||
|
- Acrylic case - $5
|
||||||
|
|
||||||
|
#### 🧠 Best for AI: Orange Pi 5 Kit (~$120)
|
||||||
|
|
||||||
|
**What to buy:**
|
||||||
|
- Orange Pi 5 (8GB RAM) - $89
|
||||||
|
- 12V 2A power supply - $10
|
||||||
|
- 64GB microSD or NVMe SSD - $15
|
||||||
|
- Cooling fan case - $10
|
||||||
|
|
||||||
|
This board has a 6 TOPS NPU for accelerated AI inference!
|
||||||
|
|
||||||
|
## What Else Do I Need?
|
||||||
|
|
||||||
|
### Essential Accessories
|
||||||
|
|
||||||
|
| Item | Purpose | Price Range |
|
||||||
|
|------|---------|-------------|
|
||||||
|
| microSD Card | Operating system storage | $8-15 |
|
||||||
|
| Power Supply | Power the board | $8-15 |
|
||||||
|
| Ethernet Cable | Wired network (faster) | $5 |
|
||||||
|
| HDMI Cable | Connect to monitor/TV | $5-10 |
|
||||||
|
| USB Keyboard | Initial setup | $10-20 |
|
||||||
|
|
||||||
|
### For Display Projects
|
||||||
|
|
||||||
|
| Item | Purpose | Price Range |
|
||||||
|
|------|---------|-------------|
|
||||||
|
| **3.5" TFT LCD** | Small color touchscreen | $15-25 |
|
||||||
|
| **7" HDMI LCD** | Larger display | $40-60 |
|
||||||
|
| **16x2 LCD** | Simple text display | $5-10 |
|
||||||
|
| **0.96" OLED** | Tiny status display | $5-8 |
|
||||||
|
|
||||||
|
### For Home Automation
|
||||||
|
|
||||||
|
| Item | Purpose | Price Range |
|
||||||
|
|------|---------|-------------|
|
||||||
|
| **Relay Module (4ch)** | Control lights, appliances | $5-10 |
|
||||||
|
| **DHT22 Sensor** | Temperature & humidity | $5-8 |
|
||||||
|
| **PIR Sensor** | Motion detection | $3-5 |
|
||||||
|
| **Buzzer** | Alerts and notifications | $2-3 |
|
||||||
|
| **Jumper Wires** | Connect components | $3-5 |
|
||||||
|
| **Breadboard** | Prototyping | $3-5 |
|
||||||
|
|
||||||
|
## Sample Shopping Lists
|
||||||
|
|
||||||
|
### Home Temperature Monitor ($45)
|
||||||
|
|
||||||
|
Perfect first project - monitor and log temperature!
|
||||||
|
|
||||||
|
```
|
||||||
|
□ Orange Pi Zero 3 (1GB) $20
|
||||||
|
□ 16GB microSD card $5
|
||||||
|
□ 5V 2A power supply $5
|
||||||
|
□ DHT22 temperature sensor $6
|
||||||
|
□ 0.96" OLED display (I2C) $6
|
||||||
|
□ Jumper wires (female-female) $3
|
||||||
|
─────────────
|
||||||
|
Total: $45
|
||||||
|
```
|
||||||
|
|
||||||
|
### Smart Doorbell ($70)
|
||||||
|
|
||||||
|
AI-powered doorbell with notifications!
|
||||||
|
|
||||||
|
```
|
||||||
|
□ Raspberry Pi Zero 2 W $15
|
||||||
|
□ Pi Camera Module $25
|
||||||
|
□ Push button $1
|
||||||
|
□ Piezo buzzer $2
|
||||||
|
□ LED (with resistor) $1
|
||||||
|
□ 16GB microSD card $5
|
||||||
|
□ 5V 2.5A power supply $8
|
||||||
|
□ Case $5
|
||||||
|
□ Jumper wires $3
|
||||||
|
─────────────
|
||||||
|
Total: $70
|
||||||
|
```
|
||||||
|
|
||||||
|
### Offline AI Assistant ($150)
|
||||||
|
|
||||||
|
Run AI completely offline - no internet needed!
|
||||||
|
|
||||||
|
```
|
||||||
|
□ Orange Pi 5 (8GB RAM) $89
|
||||||
|
□ 128GB NVMe SSD $20
|
||||||
|
□ 12V 3A power supply $12
|
||||||
|
□ 7" HDMI touchscreen $45
|
||||||
|
□ USB microphone $10
|
||||||
|
□ Case with fan $15
|
||||||
|
□ Jumper wires $3
|
||||||
|
─────────────
|
||||||
|
Total: ~$195
|
||||||
|
```
|
||||||
|
|
||||||
|
### Voice-Controlled Lights ($55)
|
||||||
|
|
||||||
|
Control your lights by talking!
|
||||||
|
|
||||||
|
```
|
||||||
|
□ Raspberry Pi 4 (2GB) $35
|
||||||
|
□ 4-channel relay module $6
|
||||||
|
□ USB microphone $8
|
||||||
|
□ 16GB microSD card $5
|
||||||
|
□ 5V 3A power supply $8
|
||||||
|
□ Jumper wires $3
|
||||||
|
─────────────
|
||||||
|
Total: ~$65
|
||||||
|
```
|
||||||
|
|
||||||
|
## Where to Buy (By Region)
|
||||||
|
|
||||||
|
### United States
|
||||||
|
- **Amazon** - Fast shipping, good returns
|
||||||
|
- **Adafruit** - Quality accessories, great tutorials
|
||||||
|
- **SparkFun** - Sensors and components
|
||||||
|
- **Micro Center** - If you have one nearby!
|
||||||
|
|
||||||
|
### Europe
|
||||||
|
- **The Pi Hut** (UK) - Official Pi reseller
|
||||||
|
- **Pimoroni** (UK) - Creative accessories
|
||||||
|
- **Amazon.de/.fr/.es** - Local shipping
|
||||||
|
- **Conrad** (Germany) - Electronics store
|
||||||
|
|
||||||
|
### Asia
|
||||||
|
- **AliExpress** - Cheapest, 2-4 week shipping
|
||||||
|
- **Taobao** (China) - Even cheaper if you read Chinese
|
||||||
|
- **Amazon.co.jp** (Japan)
|
||||||
|
|
||||||
|
### South America
|
||||||
|
- **MercadoLivre** (Brazil) - Local marketplace
|
||||||
|
- **FilipeFlop** (Brazil) - Arduino/Pi specialist
|
||||||
|
- **Amazon.com.br** - Limited selection
|
||||||
|
|
||||||
|
### Tips for AliExpress
|
||||||
|
- Check seller ratings (97%+ is good)
|
||||||
|
- Read reviews with photos
|
||||||
|
- Expect 2-4 weeks shipping
|
||||||
|
- Buy from China Direct for best prices
|
||||||
|
- Consider "Choice" items for faster shipping
|
||||||
|
|
||||||
|
## First-Time Setup Guide
|
||||||
|
|
||||||
|
### Step 1: Flash the OS
|
||||||
|
|
||||||
|
1. Download [Raspberry Pi Imager](https://www.raspberrypi.com/software/)
|
||||||
|
2. Insert your microSD card
|
||||||
|
3. Select:
|
||||||
|
- **Device**: Your board
|
||||||
|
- **OS**: Raspberry Pi OS Lite (64-bit)
|
||||||
|
- **Storage**: Your microSD
|
||||||
|
4. Click **EDIT SETTINGS**:
|
||||||
|
- Set hostname: `mybot`
|
||||||
|
- Enable SSH
|
||||||
|
- Set username/password
|
||||||
|
- Configure WiFi
|
||||||
|
5. Click **WRITE**
|
||||||
|
|
||||||
|
### Step 2: First Boot
|
||||||
|
|
||||||
|
1. Insert microSD into your SBC
|
||||||
|
2. Connect power
|
||||||
|
3. Wait 2 minutes for first boot
|
||||||
|
4. Find your device:
|
||||||
|
```bash
|
||||||
|
# On your computer
|
||||||
|
ping mybot.local
|
||||||
|
# or check your router's device list
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Connect via SSH
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh pi@mybot.local
|
||||||
|
# Enter your password
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Install General Bots
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Quick install
|
||||||
|
curl -fsSL https://get.generalbots.com | bash
|
||||||
|
|
||||||
|
# Or use the deploy script
|
||||||
|
git clone https://github.com/GeneralBots/botserver.git
|
||||||
|
cd botserver
|
||||||
|
./scripts/deploy-embedded.sh --local --with-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 5: Access the Interface
|
||||||
|
|
||||||
|
Open in your browser:
|
||||||
|
```
|
||||||
|
http://mybot.local:8088
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Beginner Mistakes
|
||||||
|
|
||||||
|
### ❌ Wrong Power Supply
|
||||||
|
|
||||||
|
**Problem**: Board keeps rebooting or won't start
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Raspberry Pi 4/5: Use **official** 5V 3A USB-C PSU
|
||||||
|
- Orange Pi 5: Use **12V** 2A, not 5V!
|
||||||
|
- Don't use phone chargers - they can't supply enough current
|
||||||
|
|
||||||
|
### ❌ Cheap/Slow microSD Card
|
||||||
|
|
||||||
|
**Problem**: Slow boot, random crashes, data corruption
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Buy **Class 10** or **A1/A2** rated cards
|
||||||
|
- Good brands: SanDisk, Samsung, Kingston
|
||||||
|
- Avoid no-name cards from AliExpress
|
||||||
|
|
||||||
|
### ❌ No Heatsink/Cooling
|
||||||
|
|
||||||
|
**Problem**: Board throttles or overheats
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Always use heatsinks on the CPU
|
||||||
|
- Consider a fan for Pi 4/5 or Orange Pi 5
|
||||||
|
- Use a case with ventilation
|
||||||
|
|
||||||
|
### ❌ Connecting to Wrong Voltage
|
||||||
|
|
||||||
|
**Problem**: Fried components, magic smoke
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Raspberry Pi GPIO is **3.3V** only!
|
||||||
|
- Never connect 5V to GPIO pins
|
||||||
|
- Use level shifters for 5V sensors
|
||||||
|
|
||||||
|
## Getting Help
|
||||||
|
|
||||||
|
### Community Resources
|
||||||
|
|
||||||
|
- [Raspberry Pi Forums](https://forums.raspberrypi.com)
|
||||||
|
- [Orange Pi Forums](http://www.orangepi.org/orangepibbsen/)
|
||||||
|
- [General Bots Discord](https://discord.gg/generalbots)
|
||||||
|
- [r/raspberry_pi](https://reddit.com/r/raspberry_pi)
|
||||||
|
|
||||||
|
### Recommended YouTube Channels
|
||||||
|
|
||||||
|
- **ExplainingComputers** - Great SBC reviews
|
||||||
|
- **Jeff Geerling** - Deep Pi tutorials
|
||||||
|
- **Andreas Spiess** - IoT and sensors
|
||||||
|
- **DroneBot Workshop** - Beginner friendly
|
||||||
|
|
||||||
|
### Books
|
||||||
|
|
||||||
|
- "Getting Started with Raspberry Pi" - Matt Richardson
|
||||||
|
- "Make: Electronics" - Charles Platt
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
Once you have your SBC:
|
||||||
|
|
||||||
|
1. **[Quick Start Guide](./quick-start.md)** - Get GB running in 5 minutes
|
||||||
|
2. **[GPIO Keywords](../06-gbdialog/keywords-gpio.md)** - Control hardware with BASIC
|
||||||
|
3. **[Templates](../02-templates/template-embedded.md)** - Ready-made automation projects
|
||||||
|
4. **[Local LLM](./local-llm.md)** - Add offline AI capabilities
|
||||||
|
|
||||||
|
Happy building! 🤖
|
||||||
|
|
@ -4,15 +4,15 @@ Deploy General Bots as the primary interface on Android and HarmonyOS devices, t
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
BotOS transforms any Android or HarmonyOS device into a dedicated General Bots system, removing manufacturer bloatware and installing GB as the default launcher.
|
BotDevice transforms any Android or HarmonyOS device into a dedicated General Bots system, removing manufacturer bloatware and installing GB as the default launcher.
|
||||||
|
|
||||||
```
|
```
|
||||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||||
│ BotOS Architecture │
|
│ BotDevice Architecture │
|
||||||
├─────────────────────────────────────────────────────────────────────────────┤
|
├─────────────────────────────────────────────────────────────────────────────┤
|
||||||
│ │
|
│ │
|
||||||
│ ┌──────────────────────────────────────────────────────────────────┐ │
|
│ ┌──────────────────────────────────────────────────────────────────┐ │
|
||||||
│ │ BotOS App (Tauri) │ │
|
│ │ BotDevice App (Tauri) │ │
|
||||||
│ ├──────────────────────────────────────────────────────────────────┤ │
|
│ ├──────────────────────────────────────────────────────────────────┤ │
|
||||||
│ │ botui/ui/suite │ Tauri Android │ src/lib.rs (Rust) │ │
|
│ │ botui/ui/suite │ Tauri Android │ src/lib.rs (Rust) │ │
|
||||||
│ │ (Web Interface) │ (WebView + NDK) │ (Backend + Hardware) │ │
|
│ │ (Web Interface) │ (WebView + NDK) │ (Backend + Hardware) │ │
|
||||||
|
|
@ -46,18 +46,18 @@ BotOS transforms any Android or HarmonyOS device into a dedicated General Bots s
|
||||||
|
|
||||||
| Level | Requirements | What It Does |
|
| Level | Requirements | What It Does |
|
||||||
|-------|-------------|--------------|
|
|-------|-------------|--------------|
|
||||||
| **Level 1** | ADB only | Removes bloatware, installs BotOS as app |
|
| **Level 1** | ADB only | Removes bloatware, installs BotDevice as app |
|
||||||
| **Level 2** | Root + Magisk | GB boot animation, BotOS as system app |
|
| **Level 2** | Root + Magisk | GB boot animation, BotDevice as system app |
|
||||||
| **Level 3** | Unlocked bootloader | Full Android replacement with BotOS |
|
| **Level 3** | Unlocked bootloader | Full Android replacement with BotDevice |
|
||||||
|
|
||||||
## Quick Installation
|
## Quick Installation
|
||||||
|
|
||||||
### Level 1: Debloat + App (No Root)
|
### Level 1: Debloat + App (No Root)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone botos repository
|
# Clone botdevice repository
|
||||||
git clone https://github.com/GeneralBots/botos.git
|
git clone https://github.com/GeneralBots/botdevice.git
|
||||||
cd botos/rom
|
cd botdevice/rom
|
||||||
|
|
||||||
# Connect device via USB (enable USB debugging first)
|
# Connect device via USB (enable USB debugging first)
|
||||||
./install.sh
|
./install.sh
|
||||||
|
|
@ -66,18 +66,18 @@ cd botos/rom
|
||||||
The interactive installer will:
|
The interactive installer will:
|
||||||
1. Detect your device and manufacturer
|
1. Detect your device and manufacturer
|
||||||
2. Remove bloatware automatically
|
2. Remove bloatware automatically
|
||||||
3. Install BotOS APK
|
3. Install BotDevice APK
|
||||||
4. Optionally set as default launcher
|
4. Optionally set as default launcher
|
||||||
|
|
||||||
### Level 2: Magisk Module (Root Required)
|
### Level 2: Magisk Module (Root Required)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Generate Magisk module
|
# Generate Magisk module
|
||||||
cd botos/rom/scripts
|
cd botdevice/rom/scripts
|
||||||
./build-magisk-module.sh
|
./build-magisk-module.sh
|
||||||
|
|
||||||
# Copy to device
|
# Copy to device
|
||||||
adb push botos-magisk-v1.0.zip /sdcard/
|
adb push botdevice-magisk-v1.0.zip /sdcard/
|
||||||
|
|
||||||
# Install via Magisk app
|
# Install via Magisk app
|
||||||
# Magisk → Modules → + → Select ZIP → Reboot
|
# Magisk → Modules → + → Select ZIP → Reboot
|
||||||
|
|
@ -85,12 +85,12 @@ adb push botos-magisk-v1.0.zip /sdcard/
|
||||||
|
|
||||||
This adds:
|
This adds:
|
||||||
- Custom boot animation
|
- Custom boot animation
|
||||||
- BotOS as system app (privileged permissions)
|
- BotDevice as system app (privileged permissions)
|
||||||
- Debloat via overlay
|
- Debloat via overlay
|
||||||
|
|
||||||
### Level 3: GSI (Full Replacement)
|
### Level 3: GSI (Full Replacement)
|
||||||
|
|
||||||
For advanced users with unlocked bootloader. See `botos/rom/gsi/README.md`.
|
For advanced users with unlocked bootloader. See `botdevice/rom/gsi/README.md`.
|
||||||
|
|
||||||
## Bloatware Removed
|
## Bloatware Removed
|
||||||
|
|
||||||
|
|
@ -143,7 +143,7 @@ sudo apt install librsvg2-bin imagemagick
|
||||||
### Build APK
|
### Build APK
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd botos
|
cd botdevice
|
||||||
|
|
||||||
# Generate icons from SVG
|
# Generate icons from SVG
|
||||||
./scripts/generate-icons.sh
|
./scripts/generate-icons.sh
|
||||||
|
|
@ -164,14 +164,14 @@ Output: `gen/android/app/build/outputs/apk/release/app-release.apk`
|
||||||
cargo tauri android dev
|
cargo tauri android dev
|
||||||
|
|
||||||
# Watch logs
|
# Watch logs
|
||||||
adb logcat -s BotOS:*
|
adb logcat -s BotDevice:*
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
### AndroidManifest.xml
|
### AndroidManifest.xml
|
||||||
|
|
||||||
BotOS is configured as a launcher:
|
BotDevice is configured as a launcher:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
@ -214,7 +214,7 @@ Create custom boot animation with GB branding:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Generate animation
|
# Generate animation
|
||||||
cd botos/scripts
|
cd botdevice/scripts
|
||||||
./create-bootanimation.sh
|
./create-bootanimation.sh
|
||||||
|
|
||||||
# Install (requires root)
|
# Install (requires root)
|
||||||
|
|
@ -227,7 +227,7 @@ adb reboot
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
botos/
|
botdevice/
|
||||||
├── Cargo.toml # Rust/Tauri dependencies
|
├── Cargo.toml # Rust/Tauri dependencies
|
||||||
├── tauri.conf.json # Tauri config → botui/ui/suite
|
├── tauri.conf.json # Tauri config → botui/ui/suite
|
||||||
├── build.rs # Build script
|
├── build.rs # Build script
|
||||||
|
|
@ -261,7 +261,7 @@ botos/
|
||||||
|
|
||||||
## Offline Mode
|
## Offline Mode
|
||||||
|
|
||||||
BotOS can work offline with local LLM:
|
BotDevice can work offline with local LLM:
|
||||||
|
|
||||||
1. Install botserver on the device (see [Local LLM](./local-llm.md))
|
1. Install botserver on the device (see [Local LLM](./local-llm.md))
|
||||||
2. Configure to use localhost:
|
2. Configure to use localhost:
|
||||||
|
|
@ -298,7 +298,7 @@ BotOS can work offline with local LLM:
|
||||||
# Settings → Security → Unknown Sources
|
# Settings → Security → Unknown Sources
|
||||||
|
|
||||||
# Or use ADB
|
# Or use ADB
|
||||||
adb install -r botos.apk
|
adb install -r botdevice.apk
|
||||||
```
|
```
|
||||||
|
|
||||||
### Debloat Not Working
|
### Debloat Not Working
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
- [Template: CRM Contacts](./02-templates/template-crm-contacts.md)
|
- [Template: CRM Contacts](./02-templates/template-crm-contacts.md)
|
||||||
- [Template: Attendance CRM](./02-templates/template-attendance-crm.md)
|
- [Template: Attendance CRM](./02-templates/template-attendance-crm.md)
|
||||||
- [Template: Marketing](./02-templates/template-marketing.md)
|
- [Template: Marketing](./02-templates/template-marketing.md)
|
||||||
|
- [Template: Embedded Devices](./02-templates/template-embedded.md)
|
||||||
- [Template: Creating Templates](./02-templates/template-template.md)
|
- [Template: Creating Templates](./02-templates/template-template.md)
|
||||||
|
|
||||||
# Part III - Knowledge Base
|
# Part III - Knowledge Base
|
||||||
|
|
@ -201,6 +202,7 @@
|
||||||
- [QR CODE](./06-gbdialog/keyword-qrcode.md)
|
- [QR CODE](./06-gbdialog/keyword-qrcode.md)
|
||||||
- [SEND SMS](./06-gbdialog/keyword-sms.md)
|
- [SEND SMS](./06-gbdialog/keyword-sms.md)
|
||||||
- [START MEET / JOIN MEET](./06-gbdialog/keyword-start-meet.md)
|
- [START MEET / JOIN MEET](./06-gbdialog/keyword-start-meet.md)
|
||||||
|
- [GPIO & IoT Keywords](./06-gbdialog/keywords-gpio.md)
|
||||||
- [File Operations](./06-gbdialog/keywords-file.md)
|
- [File Operations](./06-gbdialog/keywords-file.md)
|
||||||
- [READ](./06-gbdialog/keyword-read.md)
|
- [READ](./06-gbdialog/keyword-read.md)
|
||||||
- [WRITE](./06-gbdialog/keyword-write.md)
|
- [WRITE](./06-gbdialog/keyword-write.md)
|
||||||
|
|
@ -323,6 +325,7 @@
|
||||||
# Part XII - Device & Offline Deployment
|
# Part XII - Device & Offline Deployment
|
||||||
|
|
||||||
- [Chapter 13: Device Deployment](./13-devices/README.md)
|
- [Chapter 13: Device Deployment](./13-devices/README.md)
|
||||||
|
- [Buying Guide for Beginners](./13-devices/buying-guide.md)
|
||||||
- [Mobile (Android & HarmonyOS)](./13-devices/mobile.md)
|
- [Mobile (Android & HarmonyOS)](./13-devices/mobile.md)
|
||||||
- [Supported Hardware (SBCs)](./13-devices/hardware.md)
|
- [Supported Hardware (SBCs)](./13-devices/hardware.md)
|
||||||
- [Quick Start](./13-devices/quick-start.md)
|
- [Quick Start](./13-devices/quick-start.md)
|
||||||
|
|
|
||||||
124
src/assets/diagrams/embedded-architecture.svg
Normal file
124
src/assets/diagrams/embedded-architecture.svg
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 500" width="1200" height="500">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.title { font: bold 20px Arial, sans-serif; fill: #333; }
|
||||||
|
.box-label { font: bold 13px Arial, sans-serif; fill: #333; }
|
||||||
|
.small-text { font: 11px Arial, sans-serif; fill: #666; }
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.title { fill: #eee; }
|
||||||
|
.box-label { fill: #eee; }
|
||||||
|
.small-text { fill: #ccc; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<rect width="100%" height="100%" fill="transparent"/>
|
||||||
|
<text x="600" y="35" text-anchor="middle" class="title">Embedded GB Architecture</text>
|
||||||
|
|
||||||
|
<!-- User Input -->
|
||||||
|
<g transform="translate(50, 60)">
|
||||||
|
<rect width="200" height="160" rx="8" fill="#E3F2FD" stroke="#1976D2" stroke-width="2"/>
|
||||||
|
<text x="100" y="25" text-anchor="middle" class="box-label">User Input</text>
|
||||||
|
<rect x="15" y="40" width="50" height="45" rx="4" fill="#BBDEFB" stroke="#1976D2"/>
|
||||||
|
<text x="40" y="68" text-anchor="middle" class="small-text">Keyboard</text>
|
||||||
|
<rect x="75" y="40" width="50" height="45" rx="4" fill="#BBDEFB" stroke="#1976D2"/>
|
||||||
|
<text x="100" y="68" text-anchor="middle" class="small-text">Touch</text>
|
||||||
|
<rect x="135" y="40" width="50" height="45" rx="4" fill="#BBDEFB" stroke="#1976D2"/>
|
||||||
|
<text x="160" y="68" text-anchor="middle" class="small-text">GPIO</text>
|
||||||
|
<rect x="15" y="95" width="170" height="50" rx="4" fill="#BBDEFB" stroke="#1976D2"/>
|
||||||
|
<text x="100" y="125" text-anchor="middle" class="small-text">Sensors (I2C/SPI)</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Display Output -->
|
||||||
|
<g transform="translate(50, 250)">
|
||||||
|
<rect width="200" height="120" rx="8" fill="#F3E5F5" stroke="#7B1FA2" stroke-width="2"/>
|
||||||
|
<text x="100" y="25" text-anchor="middle" class="box-label">Display</text>
|
||||||
|
<rect x="10" y="40" width="40" height="35" rx="4" fill="#E1BEE7" stroke="#7B1FA2"/>
|
||||||
|
<text x="30" y="62" text-anchor="middle" class="small-text">LCD</text>
|
||||||
|
<rect x="55" y="40" width="40" height="35" rx="4" fill="#E1BEE7" stroke="#7B1FA2"/>
|
||||||
|
<text x="75" y="62" text-anchor="middle" class="small-text">OLED</text>
|
||||||
|
<rect x="100" y="40" width="40" height="35" rx="4" fill="#E1BEE7" stroke="#7B1FA2"/>
|
||||||
|
<text x="120" y="62" text-anchor="middle" class="small-text">TFT</text>
|
||||||
|
<rect x="145" y="40" width="45" height="35" rx="4" fill="#E1BEE7" stroke="#7B1FA2"/>
|
||||||
|
<text x="168" y="62" text-anchor="middle" class="small-text">HDMI</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- BotServer -->
|
||||||
|
<g transform="translate(320, 80)">
|
||||||
|
<rect width="240" height="280" rx="10" fill="#E8F5E9" stroke="#388E3C" stroke-width="2"/>
|
||||||
|
<text x="120" y="30" text-anchor="middle" class="box-label">botserver (Rust)</text>
|
||||||
|
<text x="120" y="50" text-anchor="middle" class="small-text">Port 8088</text>
|
||||||
|
<rect x="20" y="70" width="200" height="40" rx="4" fill="#C8E6C9" stroke="#388E3C"/>
|
||||||
|
<text x="120" y="95" text-anchor="middle" class="small-text">BASIC Interpreter</text>
|
||||||
|
<rect x="20" y="120" width="200" height="40" rx="4" fill="#C8E6C9" stroke="#388E3C"/>
|
||||||
|
<text x="120" y="145" text-anchor="middle" class="small-text">GPIO Keywords</text>
|
||||||
|
<rect x="20" y="170" width="200" height="40" rx="4" fill="#C8E6C9" stroke="#388E3C"/>
|
||||||
|
<text x="120" y="195" text-anchor="middle" class="small-text">SQLite Database</text>
|
||||||
|
<rect x="20" y="220" width="200" height="40" rx="4" fill="#C8E6C9" stroke="#388E3C"/>
|
||||||
|
<text x="120" y="245" text-anchor="middle" class="small-text">Embedded UI Server</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- LLM Server -->
|
||||||
|
<g transform="translate(630, 80)">
|
||||||
|
<rect width="200" height="150" rx="10" fill="#FFF3E0" stroke="#F57C00" stroke-width="2"/>
|
||||||
|
<text x="100" y="30" text-anchor="middle" class="box-label">llama.cpp</text>
|
||||||
|
<text x="100" y="50" text-anchor="middle" class="small-text">Port 8080 (Optional)</text>
|
||||||
|
<rect x="20" y="70" width="160" height="30" rx="4" fill="#FFE0B2" stroke="#F57C00"/>
|
||||||
|
<text x="100" y="90" text-anchor="middle" class="small-text">TinyLlama GGUF</text>
|
||||||
|
<rect x="20" y="105" width="160" height="30" rx="4" fill="#FFE0B2" stroke="#F57C00"/>
|
||||||
|
<text x="100" y="125" text-anchor="middle" class="small-text">NPU Acceleration</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SBC Hardware -->
|
||||||
|
<g transform="translate(630, 260)">
|
||||||
|
<rect width="200" height="100" rx="10" fill="#ECEFF1" stroke="#607D8B" stroke-width="2"/>
|
||||||
|
<text x="100" y="25" text-anchor="middle" class="box-label">SBC Hardware</text>
|
||||||
|
<text x="100" y="50" text-anchor="middle" class="small-text">Orange Pi / Raspberry Pi</text>
|
||||||
|
<text x="100" y="70" text-anchor="middle" class="small-text">ARM64 CPU + NPU</text>
|
||||||
|
<text x="100" y="90" text-anchor="middle" class="small-text">1-16GB RAM</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Actuators -->
|
||||||
|
<g transform="translate(900, 80)">
|
||||||
|
<rect width="180" height="150" rx="10" fill="#FCE4EC" stroke="#C2185B" stroke-width="2"/>
|
||||||
|
<text x="90" y="25" text-anchor="middle" class="box-label">Actuators</text>
|
||||||
|
<rect x="15" y="45" width="70" height="35" rx="4" fill="#F8BBD9" stroke="#C2185B"/>
|
||||||
|
<text x="50" y="68" text-anchor="middle" class="small-text">Relay</text>
|
||||||
|
<rect x="95" y="45" width="70" height="35" rx="4" fill="#F8BBD9" stroke="#C2185B"/>
|
||||||
|
<text x="130" y="68" text-anchor="middle" class="small-text">Motor</text>
|
||||||
|
<rect x="15" y="90" width="70" height="35" rx="4" fill="#F8BBD9" stroke="#C2185B"/>
|
||||||
|
<text x="50" y="113" text-anchor="middle" class="small-text">LED</text>
|
||||||
|
<rect x="95" y="90" width="70" height="35" rx="4" fill="#F8BBD9" stroke="#C2185B"/>
|
||||||
|
<text x="130" y="113" text-anchor="middle" class="small-text">Buzzer</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Cloud (Optional) -->
|
||||||
|
<g transform="translate(900, 260)">
|
||||||
|
<rect width="180" height="100" rx="10" fill="#E0F7FA" stroke="#00838F" stroke-width="2" stroke-dasharray="5,3"/>
|
||||||
|
<text x="90" y="25" text-anchor="middle" class="box-label">Cloud (Optional)</text>
|
||||||
|
<text x="90" y="50" text-anchor="middle" class="small-text">Remote botserver</text>
|
||||||
|
<text x="90" y="70" text-anchor="middle" class="small-text">LLM APIs</text>
|
||||||
|
<text x="90" y="90" text-anchor="middle" class="small-text">Updates</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Arrows -->
|
||||||
|
<defs>
|
||||||
|
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||||
|
<polygon points="0 0, 10 3.5, 0 7" fill="#666"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Input to Server -->
|
||||||
|
<line x1="250" y1="140" x2="320" y2="180" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||||||
|
|
||||||
|
<!-- Display from Server -->
|
||||||
|
<line x1="320" y1="280" x2="250" y2="310" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||||||
|
|
||||||
|
<!-- Server to LLM -->
|
||||||
|
<line x1="560" y1="155" x2="630" y2="155" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||||||
|
|
||||||
|
<!-- Server to Actuators -->
|
||||||
|
<line x1="560" y1="200" x2="900" y2="155" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)"/>
|
||||||
|
|
||||||
|
<!-- Server to Cloud -->
|
||||||
|
<line x1="560" y1="320" x2="900" y2="310" stroke="#666" stroke-width="2" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.9 KiB |
Loading…
Add table
Reference in a new issue