Compare commits

...

3 Commits

Author SHA1 Message Date
199168550d master resets slaves 2025-05-18 15:10:17 +02:00
17da15d69f stress simulation 2025-05-18 15:09:36 +02:00
997bb3c5cf new pi based controller 2025-05-18 15:08:57 +02:00
6 changed files with 145 additions and 13 deletions

12
controller/README.md Normal file
View File

@ -0,0 +1,12 @@
# Controller
## links
* https://www.kernel.org/doc/Documentation/i2c/dev-interface
## PINs
* interal = physical = usage
* 5 = 29 = reset peripheral devices
* 0 = 27 = I2C SDA
* 1 = 28 = I2C SCL
## commands
* reset peripheral devices: `gpioset gpiochip0 5=0`

View File

@ -18,10 +18,12 @@
#define MQTT_LOG_TOPIC "/xplane/meta/log"
#define MQTT_SIM_VALUE_TOPIC "/xplane/rref/#"
#define MQTT_SIM_VALUE_SUBSCRIBE_TOPIC_PREFIX "/xplane/rref/"
#define MQTT_SIM_VALUE_SUBSCRIBE_TOPIC "/xplane/rref"
#define MQTT_SIM_VALUE_SUBSCRIBE_TOPIC "/xplane/meta/rref"
#define MQTT_KEEPALIVE_INTERVAL_MS 15000
#define SLAVE_RESET_PIN 7
struct device {
byte address; // I2C address of device
char *name; // name of this device
@ -68,6 +70,8 @@ EthernetClient client;
MqttClient mqttClient(client);
void onMqttMessage(int messageSize) {
Serial.println("Received MQTT message");
// assume, that we always receive topic beginning with MQTT_SIM_VALUE_SUBSCRIBE_TOPIC_PREFIX
// otherwise, this will _HORRIBLY_ fail
@ -113,22 +117,19 @@ void subscribeRrefs(struct device *d, int deviceNo) {
// subscribe no 1
sprintf(subscribeMsg, "%03d %03d %s", deviceNo + 1, d->rrefRefresh1, d->rref1); // subscription no is index-1 based
sendMqttMessage(MQTT_SIM_VALUE_SUBSCRIBE_TOPIC, 1, subscribeMsg);
rrefSubscriptions[deviceNo] = { d->address, TRIGGER_BIT_1 };
rrefSubscriptions[deviceNo * 2] = { d->address, TRIGGER_BIT_1 };
// subscribe no 2
sprintf(subscribeMsg, "%03d %03d %s", deviceNo + 2, d->rrefRefresh2, d->rref2); // subscription no is index-1 based
sendMqttMessage(MQTT_SIM_VALUE_SUBSCRIBE_TOPIC, 1, subscribeMsg);
rrefSubscriptions[deviceNo + 1] = { d->address, TRIGGER_BIT_2 };
}
void initializeDevices() {
for (int i = 0; i < numDevices; i++) {
sendI2CInit(devices[i]);
subscribeRrefs(&devices[i], i);
}
rrefSubscriptions[(deviceNo * 2) + 1] = { d->address, TRIGGER_BIT_2 };
}
void setup() {
// setup slave reset pin and pull it down for a reset
pinMode(SLAVE_RESET_PIN, OUTPUT);
digitalWrite(SLAVE_RESET_PIN, LOW);
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
@ -159,10 +160,12 @@ void setup() {
mqttClient.subscribe(MQTT_SIM_VALUE_TOPIC);
mqttClient.setKeepAliveInterval(MQTT_KEEPALIVE_INTERVAL_MS);
// switch on the slaves and give them a moment to boot
digitalWrite(SLAVE_RESET_PIN, HIGH);
delay(5000);
// start I2C
Wire.begin();
initializeDevices();
}
void loop() {
@ -180,6 +183,7 @@ void loop() {
// device needs initialization
sendMqttMessage(MQTT_LOG_TOPIC, 2, "got reset byte from ", devices[i].name);
sendI2CInit(devices[i]);
subscribeRrefs(&devices[i], i);
} else {
// handle as payload
if (data & TRIGGER_BIT_1) {

View File

@ -20,7 +20,7 @@
#define VALUE_BUFFER 30
#define SKIP_ROTARY_INPUTS 40
#define SKIP_ROTARY_INPUTS 50
#define INTERNAL_STATE_UNKNOWN 0
#define INTERNAL_STATE_INITIALIZED 1

View File

@ -1 +1,2 @@
main
stress

View File

@ -1 +1,2 @@
gcc -o main mqtt.c -lmosquitto main.c
gcc -o stress mqtt.c -lmosquitto stress.c

114
simulatesimulator/stress.c Normal file
View File

@ -0,0 +1,114 @@
#include <unistd.h>
#include <stdio.h>
#include <mosquitto.h>
#include <string.h>
#include <unistd.h>
#include "mqtt.h"
#include "config.h"
#define MAX_AIRSPEED 385
#define MAX_MQTT_PAYLOAD_SIZE 512
#define LOOPS 1000000
struct mosquitto *mqtt;
int airspeed = 100;
int heading = 0;
void onMessage(struct mosquitto *mqtt, void *obj, const struct mosquitto_message *message) {
char *mqttTopic;
char mqttPayload[MAX_MQTT_PAYLOAD_SIZE];
if (strcmp(message->topic, "/xplane/meta/rref") == 0) {
//requestRrefFromXPlane(message);
} else if (strcmp(message->topic, "/xplane/meta/cmnd") == 0) {
mqttTopic = NULL;
memset(mqttPayload, 0, sizeof(mqttPayload));
printf("CMD: %s\n", (char *)message->payload);
if (strcmp((char *)message->payload, "sim/autopilot/airspeed_up") == 0) {
airspeed++;
if (airspeed > MAX_AIRSPEED) {
airspeed = MAX_AIRSPEED;
} else {
// airspeed changed
mqttTopic = "/xplane/rref/2";
sprintf(mqttPayload, "%03d", airspeed);
}
printf("Airspeed: %d\n", airspeed);
} else if (strcmp((char *)message->payload, "sim/autopilot/airspeed_down") == 0) {
airspeed--;
if (airspeed < 0) {
airspeed = 0;
} else {
mqttTopic = "/xplane/rref/2";
sprintf(mqttPayload, "%03d", airspeed);
}
printf("Airspeed: %d\n", airspeed);
} else if (strcmp((char *)message->payload, "sim/autopilot/heading_up") == 0) {
heading++;
if (heading > 360) {
heading = 1;
}
mqttTopic = "/xplane/rref/1";
sprintf(mqttPayload, "%03d", heading);
printf("Heading: %d\n", heading);
} else if (strcmp((char *)message->payload, "sim/autopilot/heading_down") == 0) {
heading--;
if (heading < 0) {
heading = 359;
}
mqttTopic = "/xplane/rref/1";
sprintf(mqttPayload, "%03d", heading);
printf("Heading: %d\n", heading);
} else {
printf("unkown command %s\n", (char *)message->payload);
}
if (mqttTopic != NULL && mqttPayload != NULL) {
sendMqtt(mqtt, mqttTopic, mqttPayload, strlen(mqttPayload));
}
} else if (strcmp(message->topic, "/xplane/meta/log") == 0) {
printf("Log: %s\n", (char *)message->payload);
} else {
fprintf(stderr, "Unknown topic %s\n", message->topic);
}
}
int loop = 0;
int main() {
char mqttPayload[MAX_MQTT_PAYLOAD_SIZE];
mqtt = connectMqtt(MQTT_USER1, MQTT_PASS, onMessage);
if (mqtt == NULL) {
return -1;
}
recvMqtt(mqtt, "/xplane/meta/cmnd");
while (1) {
loop++;
if (loop > LOOPS) {
sprintf(mqttPayload, "%03d", heading);
sendMqtt(mqtt, "/xplane/rref/1", mqttPayload, strlen(mqttPayload));
sprintf(mqttPayload, "%03d", airspeed);
sendMqtt(mqtt, "/xplane/rref/2", mqttPayload, strlen(mqttPayload));
heading++;
if (heading >= 360) {
heading = 0;
}
airspeed++;
if (airspeed >= MAX_AIRSPEED) {
airspeed = 100;
}
loop = 0;
}
mosquitto_loop(mqtt, 0, 1);
}
disconnectMqtt(mqtt);
}