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
|
||||
|
||||
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) │ │
|
||||
│ │ (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 1** | ADB only | Removes bloatware, installs BotOS as app |
|
||||
| **Level 2** | Root + Magisk | GB boot animation, BotOS as system app |
|
||||
| **Level 3** | Unlocked bootloader | Full Android replacement with BotOS |
|
||||
| **Level 1** | ADB only | Removes bloatware, installs BotDevice as app |
|
||||
| **Level 2** | Root + Magisk | GB boot animation, BotDevice as system app |
|
||||
| **Level 3** | Unlocked bootloader | Full Android replacement with BotDevice |
|
||||
|
||||
## Quick Installation
|
||||
|
||||
### Level 1: Debloat + App (No Root)
|
||||
|
||||
```bash
|
||||
# Clone botos repository
|
||||
git clone https://github.com/GeneralBots/botos.git
|
||||
cd botos/rom
|
||||
# Clone botdevice repository
|
||||
git clone https://github.com/GeneralBots/botdevice.git
|
||||
cd botdevice/rom
|
||||
|
||||
# Connect device via USB (enable USB debugging first)
|
||||
./install.sh
|
||||
|
|
@ -66,18 +66,18 @@ cd botos/rom
|
|||
The interactive installer will:
|
||||
1. Detect your device and manufacturer
|
||||
2. Remove bloatware automatically
|
||||
3. Install BotOS APK
|
||||
3. Install BotDevice APK
|
||||
4. Optionally set as default launcher
|
||||
|
||||
### Level 2: Magisk Module (Root Required)
|
||||
|
||||
```bash
|
||||
# Generate Magisk module
|
||||
cd botos/rom/scripts
|
||||
cd botdevice/rom/scripts
|
||||
./build-magisk-module.sh
|
||||
|
||||
# Copy to device
|
||||
adb push botos-magisk-v1.0.zip /sdcard/
|
||||
adb push botdevice-magisk-v1.0.zip /sdcard/
|
||||
|
||||
# Install via Magisk app
|
||||
# Magisk → Modules → + → Select ZIP → Reboot
|
||||
|
|
@ -85,12 +85,12 @@ adb push botos-magisk-v1.0.zip /sdcard/
|
|||
|
||||
This adds:
|
||||
- Custom boot animation
|
||||
- BotOS as system app (privileged permissions)
|
||||
- BotDevice as system app (privileged permissions)
|
||||
- Debloat via overlay
|
||||
|
||||
### 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
|
||||
|
||||
|
|
@ -143,7 +143,7 @@ sudo apt install librsvg2-bin imagemagick
|
|||
### Build APK
|
||||
|
||||
```bash
|
||||
cd botos
|
||||
cd botdevice
|
||||
|
||||
# Generate icons from SVG
|
||||
./scripts/generate-icons.sh
|
||||
|
|
@ -164,14 +164,14 @@ Output: `gen/android/app/build/outputs/apk/release/app-release.apk`
|
|||
cargo tauri android dev
|
||||
|
||||
# Watch logs
|
||||
adb logcat -s BotOS:*
|
||||
adb logcat -s BotDevice:*
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### AndroidManifest.xml
|
||||
|
||||
BotOS is configured as a launcher:
|
||||
BotDevice is configured as a launcher:
|
||||
|
||||
```xml
|
||||
<intent-filter>
|
||||
|
|
@ -214,7 +214,7 @@ Create custom boot animation with GB branding:
|
|||
|
||||
```bash
|
||||
# Generate animation
|
||||
cd botos/scripts
|
||||
cd botdevice/scripts
|
||||
./create-bootanimation.sh
|
||||
|
||||
# Install (requires root)
|
||||
|
|
@ -227,7 +227,7 @@ adb reboot
|
|||
## Project Structure
|
||||
|
||||
```
|
||||
botos/
|
||||
botdevice/
|
||||
├── Cargo.toml # Rust/Tauri dependencies
|
||||
├── tauri.conf.json # Tauri config → botui/ui/suite
|
||||
├── build.rs # Build script
|
||||
|
|
@ -261,7 +261,7 @@ botos/
|
|||
|
||||
## 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))
|
||||
2. Configure to use localhost:
|
||||
|
|
@ -298,7 +298,7 @@ BotOS can work offline with local LLM:
|
|||
# Settings → Security → Unknown Sources
|
||||
|
||||
# Or use ADB
|
||||
adb install -r botos.apk
|
||||
adb install -r botdevice.apk
|
||||
```
|
||||
|
||||
### Debloat Not Working
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
- [Template: CRM Contacts](./02-templates/template-crm-contacts.md)
|
||||
- [Template: Attendance CRM](./02-templates/template-attendance-crm.md)
|
||||
- [Template: Marketing](./02-templates/template-marketing.md)
|
||||
- [Template: Embedded Devices](./02-templates/template-embedded.md)
|
||||
- [Template: Creating Templates](./02-templates/template-template.md)
|
||||
|
||||
# Part III - Knowledge Base
|
||||
|
|
@ -201,6 +202,7 @@
|
|||
- [QR CODE](./06-gbdialog/keyword-qrcode.md)
|
||||
- [SEND SMS](./06-gbdialog/keyword-sms.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)
|
||||
- [READ](./06-gbdialog/keyword-read.md)
|
||||
- [WRITE](./06-gbdialog/keyword-write.md)
|
||||
|
|
@ -323,6 +325,7 @@
|
|||
# Part XII - Device & Offline Deployment
|
||||
|
||||
- [Chapter 13: Device Deployment](./13-devices/README.md)
|
||||
- [Buying Guide for Beginners](./13-devices/buying-guide.md)
|
||||
- [Mobile (Android & HarmonyOS)](./13-devices/mobile.md)
|
||||
- [Supported Hardware (SBCs)](./13-devices/hardware.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