This commit is contained in:
Greenman999 2025-09-12 04:14:30 +02:00
parent 3679e3e8e8
commit 65ed4dff1d
2 changed files with 143 additions and 17 deletions

18
main.py
View file

@ -40,24 +40,8 @@ def listen_i2c(bus_number, address, register=0x00):
print("Stopped listening.")
finally:
bus.close()
print("closed bus")
def create_led_color_packet(r, g, b):
"""
Create an 8-byte packet to set LED color for I2C transfer.
Packet format:
[0x10, 0x00, R, G, B, 0x00, 0x00, checksum]
- 0x10: Command for LED color
- 0x00: Target/channel (set as needed)
- R, G, B: Color bytes (0-255)
- 0x00, 0x00: Unused
- checksum: XOR of bytes 0-6
"""
packet = [0x10, 0x00, r & 0xFF, g & 0xFF, b & 0xFF, 0x00, 0x00]
checksum = 0
for b in packet:
checksum ^= b
packet.append(checksum)
return bytes(packet)
if __name__ == "__main__":
if len(sys.argv) < 3:

142
newmain.py Executable file
View file

@ -0,0 +1,142 @@
#!/usr/bin/env python3
import sys
from smbus2 import SMBus, i2c_msg
import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)
# --- I2C Packet Creator Functions ---
class Packet:
LENGTH = 8
def __init__(self, data=None):
if data is None:
data = [0] * self.LENGTH
if len(data) != self.LENGTH:
raise ValueError(f"Packet must be {self.LENGTH} bytes")
self.bytes = list(data)
@classmethod
def from_bytes(cls, byte_list):
return cls(list(byte_list[:cls.LENGTH]))
def as_list(self):
return self.bytes
def create_motor_state_packet(fl=None, fr=None, bl=None, br=None):
def getByteForState(state):
if state is None: return 0x00
return 0x01 if state else 0x02
packet = [
0x01, 0x00,
getByteForState(fl),
getByteForState(fr),
getByteForState(bl),
getByteForState(br),
0x00
]
checksum = 0
for b in packet:
checksum ^= b
packet.append(checksum)
return Packet.from_bytes(packet)
def create_tail_wagging_packet(wagging=False):
packet = [0x02, 0x00, 0x01 if wagging else 0x00, 0x00, 0x00, 0x00, 0x00]
checksum = 0
for b in packet:
checksum ^= b
packet.append(checksum)
return Packet.from_bytes(packet)
def create_set_led_mode(mode=0):
packet = [0x02, 0x00, mode & 0xFF, 0x00, 0x00, 0x00, 0x00]
checksum = 0
for b in packet:
checksum ^= b
packet.append(checksum)
return Packet.from_bytes(packet)
# --- MQTT & I2C Integration ---
MQTT_BROKER = "192.168.188.30"
MQTT_PORT = 1883
I2C_BUS = 1
BUTTON_TOPICS = {
"drive_forward": "home/buttons/drive_forward",
"drive_backward": "home/buttons/drive_backward",
"turn_left": "home/buttons/turn_left",
"turn_right": "home/buttons/turn_right"
}
SWITCH_TOPIC = "home/switch/wag_tail"
SELECT_TOPIC = "home/select/led_mode"
LED_MODE_MAP = {
"standard": 0,
"rot": 1,
"rainbow": 2
}
def send_i2c_packet(packet: Packet, address):
with SMBus(I2C_BUS) as bus:
msg = i2c_msg.write(address, packet.as_list())
bus.i2c_rdwr(msg)
print(f"Sent I2C packet: {packet.as_list()}")
def on_connect(client, userdata, flags, rc):
print("Connected to MQTT broker")
for topic in BUTTON_TOPICS.values():
client.subscribe(topic)
print(f"Subscribed to {topic}")
client.subscribe(SWITCH_TOPIC)
print(f"Subscribed to {SWITCH_TOPIC}")
client.subscribe(SELECT_TOPIC)
print(f"Subscribed to {SELECT_TOPIC}")
def on_message(client, userdata, msg):
print(f"MQTT: {msg.topic} - {msg.payload}")
payload = msg.payload.decode().lower()
# Handle buttons
if msg.topic == BUTTON_TOPICS["drive_forward"] and payload == "on":
packet = create_motor_state_packet(fl=True, fr=True, bl=True, br=True)
send_i2c_packet(packet, 0x41)
elif msg.topic == BUTTON_TOPICS["drive_backward"] and payload == "on":
packet = create_motor_state_packet(fl=False, fr=False, bl=False, br=False)
send_i2c_packet(packet, 0x41)
elif msg.topic == BUTTON_TOPICS["turn_left"] and payload == "on":
packet = create_motor_state_packet(fl=False, fr=True, bl=False, br=True)
send_i2c_packet(packet, 0x41)
elif msg.topic == BUTTON_TOPICS["turn_right"] and payload == "on":
packet = create_motor_state_packet(fl=True, fr=False, bl=True, br=False)
send_i2c_packet(packet, 0x41)
elif msg.topic in BUTTON_TOPICS.values() and payload == "off":
send_i2c_packet(create_motor_state_packet(), 0x41)
# Handle wag tail switch: expects "ON" or "OFF"
elif msg.topic == SWITCH_TOPIC:
# wag = payload == "on"
# if wag:
# GPIO.output(17, True)
# else:
# GPIO.output(17, False)
packet = create_tail_wagging_packet(payload == "on")
send_i2c_packet(packet, 0x43)
# Handle led mode select: expects "standard", "rot", "rainbow"
elif msg.topic == SELECT_TOPIC:
if payload in LED_MODE_MAP:
mode = LED_MODE_MAP[payload]
packet = create_set_led_mode(mode)
send_i2c_packet(packet, 0x03)
print(f"LED mode set to {payload} ({mode})")
else:
print(f"Unknown LED mode: {payload}")
def main():
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set("mqtt", "mqtt")
client.connect(MQTT_BROKER, MQTT_PORT, 60)
print("MQTT client started. Waiting for button/switch/select events...")
client.loop_forever()
if __name__ == "__main__":
main()