529 lines
11 KiB
Markdown
529 lines
11 KiB
Markdown
|
|
# 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
|