Init Repository
This commit is contained in:
commit
8da62d2072
91
Readme.md
Normal file
91
Readme.md
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# Vision AI V2 Kit mit MQTT und Wi-Fi
|
||||||
|
|
||||||
|
## Projektbeschreibung
|
||||||
|
Dieses Projekt verbindet das Vision AI V2 Kit mit einem ESP32-S3 Mikrocontroller. Es ermöglicht die Verarbeitung von Bilderkennungsdaten mit dem Grove Vision AI-Modul und die Übertragung der Ergebnisse an einen MQTT-Broker über Wi-Fi.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- Bilderkennung mit dem Grove Vision AI-Modul
|
||||||
|
- Verbindung zu einem Wi-Fi-Netzwerk
|
||||||
|
- Übertragung der Erkennungsdaten an einen MQTT-Broker
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
### Hardware
|
||||||
|
- Grove Vision AI V2 Kit
|
||||||
|
- Seeed XIAO ESP32-S3
|
||||||
|
|
||||||
|
### Software
|
||||||
|
- Arduino IDE (empfohlen: Version 1.8 oder höher)
|
||||||
|
- Abhängigkeiten:
|
||||||
|
- [Seeed_Arduino_SSCMA](https://github.com/Seeed-Studio/Seeed_Arduino_SSCMA)
|
||||||
|
- [PubSubClient](https://github.com/knolleary/pubsubclient)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Einrichtung
|
||||||
|
|
||||||
|
### 1. Hardware aufbauen
|
||||||
|
- Stecke das XIAO ESP32-S3 auf das Vision AI V2 Kit.
|
||||||
|
- Verbinde die Stromversorgung über USB.
|
||||||
|
|
||||||
|
### 2. Software vorbereiten
|
||||||
|
1. Installiere die benötigten Bibliotheken:
|
||||||
|
- Öffne den Bibliotheksmanager in der Arduino IDE und suche nach:
|
||||||
|
- `Seeed_Arduino_SSCMA`
|
||||||
|
- `PubSubClient`
|
||||||
|
2. Lade den Sketch `inference_wifi_mqtt.ino` in die Arduino IDE.
|
||||||
|
|
||||||
|
### 3. Wi-Fi und MQTT konfigurieren
|
||||||
|
- Ändere folgende Zeilen im Sketch:
|
||||||
|
```cpp
|
||||||
|
const char* ssid = "DEIN_WIFI_SSID";
|
||||||
|
const char* password = "DEIN_WIFI_PASSWORT";
|
||||||
|
const char* mqtt_server = "DEINE_MQTT_BROKER_ADRESSE";
|
||||||
|
```
|
||||||
|
- Ersetze die Platzhalter durch deine Netzwerk- und MQTT-Zugangsdaten.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verwendung
|
||||||
|
1. Lade den Sketch auf das XIAO ESP32-S3 hoch.
|
||||||
|
2. Öffne den seriellen Monitor in der Arduino IDE, um Debug-Informationen zu sehen.
|
||||||
|
3. Prüfe, ob das Gerät erfolgreich mit Wi-Fi und dem MQTT-Broker verbunden ist.
|
||||||
|
4. Erkennungsdaten werden bei erfolgreicher Bilderkennung an das MQTT-Topic `vision_ai/data` gesendet.
|
||||||
|
|
||||||
|
### Beispiel einer MQTT-Nachricht
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"perf": {
|
||||||
|
"prepocess": 1,
|
||||||
|
"inference": 21,
|
||||||
|
"postprocess": 0
|
||||||
|
},
|
||||||
|
"boxes": [
|
||||||
|
{
|
||||||
|
"target": "0",
|
||||||
|
"score": 66,
|
||||||
|
"x": 104,
|
||||||
|
"y": 76,
|
||||||
|
"w": 97,
|
||||||
|
"h": 138
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fehlerbehebung
|
||||||
|
- **Keine Verbindung zu Wi-Fi:** Stelle sicher, dass SSID und Passwort korrekt sind.
|
||||||
|
- **MQTT-Daten werden nicht gesendet:** Prüfe die Broker-Adresse und die Verbindung mit einem MQTT-Client wie MQTT Explorer.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Autor
|
||||||
|
**Joachim Hummel**
|
||||||
|
|
||||||
|
### Datum
|
||||||
|
22.01.2025
|
||||||
|
|
226
nodered-flow.json
Normal file
226
nodered-flow.json
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "820464e1e8b08b98",
|
||||||
|
"type": "tab",
|
||||||
|
"label": "Flow 5",
|
||||||
|
"disabled": false,
|
||||||
|
"info": "",
|
||||||
|
"env": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "af726d45933680e7",
|
||||||
|
"type": "mqtt in",
|
||||||
|
"z": "820464e1e8b08b98",
|
||||||
|
"name": "",
|
||||||
|
"topic": "/vision_ai/data",
|
||||||
|
"qos": "2",
|
||||||
|
"datatype": "auto-detect",
|
||||||
|
"broker": "ec7d072cfbe377c3",
|
||||||
|
"nl": false,
|
||||||
|
"rap": true,
|
||||||
|
"rh": 0,
|
||||||
|
"inputs": 0,
|
||||||
|
"x": 180,
|
||||||
|
"y": 80,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"2"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"type": "function",
|
||||||
|
"z": "820464e1e8b08b98",
|
||||||
|
"name": "Extract Score",
|
||||||
|
"func": "// Check if payload and boxes exist\nif (msg.payload && msg.payload.boxes && msg.payload.boxes[0]) {\n let score = msg.payload.boxes[0].score; // Extrahiere den Score-Wert\n if (score > 70) {\n msg.payload = score; // Setze den Score als neue Payload\n return msg; // Sende die Nachricht nur, wenn Score > 40\n }\n}\n// Wenn die Bedingung nicht erfüllt ist, ignoriere die Nachricht\nreturn null;\n",
|
||||||
|
"outputs": 1,
|
||||||
|
"timeout": "",
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 400,
|
||||||
|
"y": 80,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"3",
|
||||||
|
"a21e33088a66bf25"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "820464e1e8b08b98",
|
||||||
|
"name": "Score Output",
|
||||||
|
"active": false,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "payload",
|
||||||
|
"targetType": "msg",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 620,
|
||||||
|
"y": 80,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a21e33088a66bf25",
|
||||||
|
"type": "trigger",
|
||||||
|
"z": "820464e1e8b08b98",
|
||||||
|
"name": "",
|
||||||
|
"op1": "1",
|
||||||
|
"op2": "0",
|
||||||
|
"op1type": "str",
|
||||||
|
"op2type": "str",
|
||||||
|
"duration": "30",
|
||||||
|
"extend": false,
|
||||||
|
"overrideDelay": false,
|
||||||
|
"units": "s",
|
||||||
|
"reset": "",
|
||||||
|
"bytopic": "all",
|
||||||
|
"topic": "topic",
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 590,
|
||||||
|
"y": 140,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"10f102b739a73c2f",
|
||||||
|
"0c95c988ea6f3da4"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10f102b739a73c2f",
|
||||||
|
"type": "debug",
|
||||||
|
"z": "820464e1e8b08b98",
|
||||||
|
"name": "debug 10",
|
||||||
|
"active": true,
|
||||||
|
"tosidebar": true,
|
||||||
|
"console": false,
|
||||||
|
"tostatus": false,
|
||||||
|
"complete": "false",
|
||||||
|
"statusVal": "",
|
||||||
|
"statusType": "auto",
|
||||||
|
"x": 800,
|
||||||
|
"y": 140,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "09d3a894fe6a8d1c",
|
||||||
|
"type": "telegram sender",
|
||||||
|
"z": "98",
|
||||||
|
"name": "",
|
||||||
|
"bot": "8",
|
||||||
|
"haserroroutput": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 1000,
|
||||||
|
"y": 200,
|
||||||
|
"wires": [
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d1b95759670f38c9",
|
||||||
|
"type": "function",
|
||||||
|
"z": "820464e1e8b08b98",
|
||||||
|
"name": "function 4",
|
||||||
|
"func": "var msg1 = msg.payload.text;\nmsg.payload = {}\nmsg.payload.chatId = xxxxx\nmsg.payload.type = \"message\"\nmsg.payload.content = \"Vision AI hat ein Gesicht erkannt\";\nreturn msg;",
|
||||||
|
"outputs": 1,
|
||||||
|
"timeout": 0,
|
||||||
|
"noerr": 0,
|
||||||
|
"initialize": "",
|
||||||
|
"finalize": "",
|
||||||
|
"libs": [],
|
||||||
|
"x": 820,
|
||||||
|
"y": 200,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"09d3a894fe6a8d1c"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0c95c988ea6f3da4",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "820464e1e8b08b98",
|
||||||
|
"name": "",
|
||||||
|
"property": "payload",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "1",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 1,
|
||||||
|
"x": 670,
|
||||||
|
"y": 200,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"d1b95759670f38c9"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ec7d072cfbe377c3",
|
||||||
|
"type": "mqtt-broker",
|
||||||
|
"name": "192.168.1.1",
|
||||||
|
"broker": "192.168.1.1",
|
||||||
|
"port": 1883,
|
||||||
|
"clientid": "",
|
||||||
|
"autoConnect": true,
|
||||||
|
"usetls": false,
|
||||||
|
"protocolVersion": 4,
|
||||||
|
"keepalive": 60,
|
||||||
|
"cleansession": true,
|
||||||
|
"autoUnsubscribe": true,
|
||||||
|
"birthTopic": "",
|
||||||
|
"birthQos": "0",
|
||||||
|
"birthRetain": "false",
|
||||||
|
"birthPayload": "",
|
||||||
|
"birthMsg": {},
|
||||||
|
"closeTopic": "",
|
||||||
|
"closeQos": "0",
|
||||||
|
"closeRetain": "false",
|
||||||
|
"closePayload": "",
|
||||||
|
"closeMsg": {},
|
||||||
|
"willTopic": "",
|
||||||
|
"willQos": "0",
|
||||||
|
"willRetain": "false",
|
||||||
|
"willPayload": "",
|
||||||
|
"willMsg": {},
|
||||||
|
"userProps": "",
|
||||||
|
"sessionExpiry": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "564dc6ebc99bca08",
|
||||||
|
"type": "telegram bot",
|
||||||
|
"botname": "xxxx_bot",
|
||||||
|
"usernames": "xxxx",
|
||||||
|
"chatids": "",
|
||||||
|
"baseapiurl": "",
|
||||||
|
"updatemode": "polling",
|
||||||
|
"pollinterval": 300,
|
||||||
|
"usesocks": false,
|
||||||
|
"sockshost": "",
|
||||||
|
"socksprotocol": "socks5",
|
||||||
|
"socksport": 6667,
|
||||||
|
"socksusername": "anonymous",
|
||||||
|
"sockspassword": "",
|
||||||
|
"bothost": "",
|
||||||
|
"botpath": "",
|
||||||
|
"localbotport": 8443,
|
||||||
|
"publicbotport": 8443,
|
||||||
|
"privatekey": "",
|
||||||
|
"certificate": "",
|
||||||
|
"useselfsignedcertificate": false,
|
||||||
|
"sslterminated": false,
|
||||||
|
"verboselogging": false
|
||||||
|
}
|
||||||
|
]
|
103
vision-ai.ino
Normal file
103
vision-ai.ino
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Name: Joachim Hummel
|
||||||
|
// Erstellungsdatum: 22.01.2025
|
||||||
|
// Hardware: Vision AI V2 Kit
|
||||||
|
|
||||||
|
|
||||||
|
#include <Seeed_Arduino_SSCMA.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <PubSubClient.h>
|
||||||
|
|
||||||
|
// Wi-Fi-Zugangsdaten
|
||||||
|
const char* ssid = "DEIN_WIFI_SSID";
|
||||||
|
const char* password = "DEIN_WIFI_PASSWORT";
|
||||||
|
|
||||||
|
// MQTT-Broker-Zugangsdaten
|
||||||
|
const char* mqtt_server = "DEINE_MQTT_BROKER_ADRESSE";
|
||||||
|
const char* mqtt_topic = "/vision_ai/data";
|
||||||
|
|
||||||
|
WiFiClient espClient;
|
||||||
|
PubSubClient client(espClient);
|
||||||
|
SSCMA AI;
|
||||||
|
|
||||||
|
void setupWiFi() {
|
||||||
|
delay(10);
|
||||||
|
Serial.println("Verbinde mit Wi-Fi...");
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println("\nWi-Fi verbunden.");
|
||||||
|
Serial.println("IP-Adresse: " + WiFi.localIP().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void reconnectMQTT() {
|
||||||
|
while (!client.connected()) {
|
||||||
|
Serial.print("Verbinde mit MQTT...");
|
||||||
|
if (client.connect("Grove_Vision_AI")) {
|
||||||
|
Serial.println("Verbunden.");
|
||||||
|
} else {
|
||||||
|
Serial.print("Fehler. Status: ");
|
||||||
|
Serial.println(client.state());
|
||||||
|
delay(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200); // Debug-Ausgabe
|
||||||
|
AI.begin();
|
||||||
|
|
||||||
|
// Wi-Fi und MQTT initialisieren
|
||||||
|
setupWiFi();
|
||||||
|
client.setServer(mqtt_server, 1883);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// MQTT-Server verbunden halten
|
||||||
|
if (!client.connected()) {
|
||||||
|
reconnectMQTT();
|
||||||
|
}
|
||||||
|
client.loop();
|
||||||
|
|
||||||
|
// Grove Vision AI verarbeiten
|
||||||
|
if (!AI.invoke()) {
|
||||||
|
Serial.println("Erkennung erfolgreich.");
|
||||||
|
Serial.print("perf: prepocess=");
|
||||||
|
Serial.print(AI.perf().prepocess);
|
||||||
|
Serial.print(", inference=");
|
||||||
|
Serial.print(AI.perf().inference);
|
||||||
|
Serial.print(", postpocess=");
|
||||||
|
Serial.println(AI.perf().postprocess);
|
||||||
|
|
||||||
|
String mqttMessage = "{"; // MQTT-Nachricht erstellen
|
||||||
|
mqttMessage += "\"perf\":{\"prepocess\":" + String(AI.perf().prepocess);
|
||||||
|
mqttMessage += ",\"inference\":" + String(AI.perf().inference);
|
||||||
|
mqttMessage += ",\"postprocess\":" + String(AI.perf().postprocess) + "},";
|
||||||
|
|
||||||
|
mqttMessage += "\"boxes\": [";
|
||||||
|
for (int i = 0; i < AI.boxes().size(); i++) {
|
||||||
|
mqttMessage += "{\"target\":\"" + String(AI.boxes()[i].target) + "\",";
|
||||||
|
mqttMessage += "\"score\":" + String(AI.boxes()[i].score) + ",";
|
||||||
|
mqttMessage += "\"x\":" + String(AI.boxes()[i].x) + ",";
|
||||||
|
mqttMessage += "\"y\":" + String(AI.boxes()[i].y) + ",";
|
||||||
|
mqttMessage += "\"w\":" + String(AI.boxes()[i].w) + ",";
|
||||||
|
mqttMessage += "\"h\":" + String(AI.boxes()[i].h) + "},";
|
||||||
|
}
|
||||||
|
if (AI.boxes().size() > 0) {
|
||||||
|
mqttMessage.remove(mqttMessage.length() - 1); // Letztes Komma entfernen
|
||||||
|
}
|
||||||
|
mqttMessage += "]}";
|
||||||
|
|
||||||
|
Serial.println("MQTT-Nachricht: " + mqttMessage);
|
||||||
|
|
||||||
|
// MQTT-Nachricht senden
|
||||||
|
if (client.publish(mqtt_topic, mqttMessage.c_str())) {
|
||||||
|
Serial.println("Daten erfolgreich an MQTT gesendet!");
|
||||||
|
} else {
|
||||||
|
Serial.println("Fehler beim Senden der MQTT-Daten.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user