From e439ac81ec2b1e39340399bae1f152ff28969324 Mon Sep 17 00:00:00 2001 From: jusax23 Date: Sun, 21 Aug 2022 14:10:45 +0200 Subject: [PATCH] initial --- BUTTONDesc.h | 47 +++++++++++ COMP.h | 54 ++++++++++++ DefaultReceiver.ino | 44 ++++++++++ GNSS.h | 195 ++++++++++++++++++++++++++++++++++++++++++++ MPU.h | 73 +++++++++++++++++ RCdata.h | 33 ++++++++ Readme.md | 2 + descriptionStruct.h | 9 ++ juPadReceiver.h | 193 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 650 insertions(+) create mode 100644 BUTTONDesc.h create mode 100644 COMP.h create mode 100644 DefaultReceiver.ino create mode 100644 GNSS.h create mode 100644 MPU.h create mode 100644 RCdata.h create mode 100644 Readme.md create mode 100644 descriptionStruct.h create mode 100644 juPadReceiver.h diff --git a/BUTTONDesc.h b/BUTTONDesc.h new file mode 100644 index 0000000..b45afcc --- /dev/null +++ b/BUTTONDesc.h @@ -0,0 +1,47 @@ +#include "descriptionStruct.h" +#define jType_ANALOG_Desc 50 +#define jType_BUTTON_Desc 51 +#define jCommand_OUT_OF_BOUND 0xff + +typedef struct{ + byte type; //jType_ANALOG_Desc || jType_BUTTON_Desc + byte command; //0-31 button channel || 0-11 + byte use = 0xff; //0-3 || 0-1 + char text[29] = "error"; //Text +}Channel_Desc_Send; + +void initBUTTON_Desc(){ + +} + +void BUTTON_DescLoop(){ + +} + +void BUTTON_DescradioTask(){ + byte num = jRCbuff[1]; + Channel_Desc_Send data; + data.type = jType_BUTTON_Desc; + data.command = num; + if(num>31){ + jSendNRF(&data, sizeof(data)); + return; + } + data.use = buttonDesc[num].use; + strncpy(data.text, buttonDesc[num].text, 29); + jSendNRF(&data, sizeof(data)); +} + +void ANALOG_DescradioTask(){ + byte num = jRCbuff[1]; + Channel_Desc_Send data; + data.type = jType_ANALOG_Desc; + data.command = num; + if(num>11){ + jSendNRF(&data, sizeof(data)); + return; + } + data.use = analogDesc[num].use; + strncpy(data.text, analogDesc[num].text, 29); + jSendNRF(&data, sizeof(data)); +} diff --git a/COMP.h b/COMP.h new file mode 100644 index 0000000..111d2dc --- /dev/null +++ b/COMP.h @@ -0,0 +1,54 @@ +#define jType_S_COMP 2 +#define jCommand_COMP_fail 0xff +//#define jCommand_Compass_Raw 0 + +typedef struct{ + byte type = jType_S_COMP; + byte command = 0; + int X; + int Y; + int Z; + int angle; +}compData; + +#ifdef jCOMP + +#include +QMC5883LCompass compass; + +void initCOMP(){ + compass.init(); +} + +void COMPLoop(){ + compass.read(); +} + +/*float Altitude = mpu6050.getAngleX()/180*PI; +float Roll = mpu6050.getAngleY()/180*PI; +float xh=compass.getX()*cos(Altitude)+compass.getZ()*sin(Altitude); +float yh=compass.getX()*sin(Roll)*sin(Altitude)+compass.getY()*cos(Roll)-compass.getZ()*sin(Roll)*cos(Altitude); +float heading = atan2(yh, xh);*/ + +void COMPradioTask(){ + compData data; + data.X = compass.getX(); + data.Y = compass.getY(); + data.Z = compass.getZ(); + data.angle = compass.getAzimuth(); + jSendNRF(&data, sizeof(data)); +} + +#else + +void initCOMP(){} + +void COMPLoop(){} + +void MPUradioTask(){ + compData data; + data.command = jCommand_COMP_fail; + jSendNRF(&data, sizeof(data)); +} + +#endif diff --git a/DefaultReceiver.ino b/DefaultReceiver.ino new file mode 100644 index 0000000..f4cce67 --- /dev/null +++ b/DefaultReceiver.ino @@ -0,0 +1,44 @@ +#include "descriptionStruct.h" + +#define myId 0x01 +#define myChannel 1 + +#define jMPU +#define jCOMP +#define jGNSS + +#define debug + +//https://dl.espressif.com/dl/package_esp32_index.json +//1.0.6 + +ChannelDesc buttonDesc[32] = { + {3,"Armed"} +}; +ChannelDesc analogDesc[12] = { + +}; + + +void onConnect(){ + +} +void onDisconnect(bool expected){ + +} + +#include "juPadReceiver.h" + +void onData(){ + //RCdata + //RCgetBTN(0-31) + //RCgetAnalog(0-11) +} + +void setup(){ + jSetup(); +} + +void loop(){ + jLoop(); +} diff --git a/GNSS.h b/GNSS.h new file mode 100644 index 0000000..9fc2f27 --- /dev/null +++ b/GNSS.h @@ -0,0 +1,195 @@ +#define jType_S_GNSS 3 +#define jCommand_GNSS_location 0 +#define jCommand_GNSS_date 1 +#define jCommand_GNSS_time 2 +#define jCommand_GNSS_speed 3 +#define jCommand_GNSS_course 4 +#define jCommand_GNSS_altitude 5 +#define jCommand_GNSS_satellites 6 +#define jCommand_GNSS_hdop 7 + +#define jCommand_GNSS_fail 0xff + +typedef struct{ + byte type = jType_S_GNSS; + byte command = jCommand_GNSS_location; + + byte isValid; + + double lat; + double lng; +}gnssLocData; +typedef struct{ + byte type = jType_S_GNSS; + byte command = jCommand_GNSS_date; + + byte isValid; + + uint32_t value; + uint16_t year; + uint8_t month; + uint8_t day; +}gnssDateData; +typedef struct{ + byte type = jType_S_GNSS; + byte command = jCommand_GNSS_time; + + byte isValid; + + uint32_t value; + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t centisecond; +}gnssTimeData; +typedef struct{ + byte type = jType_S_GNSS; + byte command = jCommand_GNSS_speed; + + byte isValid; + + double mps; +}gnssSpeedData; +typedef struct{ + byte type = jType_S_GNSS; + byte command = jCommand_GNSS_course; + + byte isValid; + + double deg; +}gnssCourseData; +typedef struct{ + byte type = jType_S_GNSS; + byte command = jCommand_GNSS_altitude; + + byte isValid; + + double m; +}gnssAltData; +typedef struct{ + byte type = jType_S_GNSS; + byte command = jCommand_GNSS_satellites; + + byte isValid; + + uint32_t n; +}gnssSatData; +typedef struct{ + byte type = jType_S_GNSS; + byte command = jCommand_GNSS_hdop; + + byte isValid; + + double hdop; +}gnssHdopData; +typedef struct{ + byte type = jType_S_GNSS; + byte command = jCommand_GNSS_fail; +}gnssFailData; + +#ifdef jGNSS + +#include + +TinyGPSPlus gps; + +void initGNSS(){ + Serial2.begin(9600, SERIAL_8N1, 16, 17); +} + +void GNSSLoop(){ + while (Serial2.available() > 0) { + int readd = Serial2.read(); + gps.encode(readd); + } +} + +void GNSSradioTask(){ + switch (jRCbuff[1]) { + case jCommand_GNSS_location:{ + gnssLocData data; + + data.isValid = gps.location.isValid()|(gps.location.isUpdated()<<1); + data.lat = gps.location.lat(); + data.lng = gps.location.lng(); + + jSendNRF(&data, sizeof(data)); + }break; + case jCommand_GNSS_date:{ + gnssDateData data; + + data.isValid = gps.date.isValid()|(gps.date.isUpdated()<<1); + data.value = gps.date.value(); + data.year = gps.date.year(); + data.month = gps.date.month(); + data.day = gps.date.day(); + + jSendNRF(&data, sizeof(data)); + }break; + case jCommand_GNSS_time:{ + gnssTimeData data; + + data.isValid = gps.time.isValid()|(gps.time.isUpdated()<<1); + data.value = gps.time.value(); + data.hour = gps.time.hour(); + data.minute = gps.time.minute(); + data.second = gps.time.second(); + data.centisecond = gps.time.centisecond(); + + jSendNRF(&data, sizeof(data)); + }break; + case jCommand_GNSS_speed:{ + gnssSpeedData data; + + data.isValid = gps.speed.isValid()|(gps.speed.isUpdated()<<1); + data.mps = gps.speed.mps(); + + jSendNRF(&data, sizeof(data)); + }break; + case jCommand_GNSS_course:{ + gnssCourseData data; + + data.isValid = gps.course.isValid()|(gps.course.isUpdated()<<1); + data.deg = gps.course.deg(); + + jSendNRF(&data, sizeof(data)); + }break; + case jCommand_GNSS_altitude:{ + gnssAltData data; + + data.isValid = gps.altitude.isValid()|(gps.altitude.isUpdated()<<1); + data.m = gps.altitude.meters(); + + jSendNRF(&data, sizeof(data)); + }break; + case jCommand_GNSS_satellites:{ + gnssSatData data; + + data.isValid = gps.satellites.isValid()|(gps.satellites.isUpdated()<<1); + data.n = gps.satellites.value(); + + jSendNRF(&data, sizeof(data)); + }break; + case jCommand_GNSS_hdop:{ + gnssHdopData data; + + data.isValid = gps.hdop.isValid()|(gps.hdop.isUpdated()<<1); + data.hdop = gps.hdop.hdop(); + + jSendNRF(&data, sizeof(data)); + }break; + } +} + +#else + +void initGNSS(){} + +void GNSSLoop(){} + +void GNSSradioTask(){ + gnssFailData data; + jSendNRF(&data, sizeof(data)); +} + +#endif diff --git a/MPU.h b/MPU.h new file mode 100644 index 0000000..37ab0e6 --- /dev/null +++ b/MPU.h @@ -0,0 +1,73 @@ +#define jType_S_MPU 1 +#define jCommand_MPU_Acc 0 +#define jCommand_MPU_Gyro 1 +#define jCommand_MPU_Angle 2 +#define jCommand_MPU_fail 0xff + +typedef struct{ + byte type = jType_S_MPU; + byte command; + float X; + float Y; + float Z; +}mpuSendData; + +#ifdef jMPU + +#include + +MPU6050 mpu6050(Wire, 0.001f, 0.999f); + +void initMPU(){ + mpu6050.begin(); + mpu6050.setGyroOffsets(-7.8,2.32,-0.22); + mpu6050.setAccXoffset(0.03,0.0,0.3); + //mpu6050.calcGyroOffsets(false,50,50); +} + +void MPULoop(){ + mpu6050.update(); +} + +void MPUradioTask(){ + switch (jRCbuff[1]) { + case jCommand_MPU_Acc:{ + mpuSendData data; + data.command = jCommand_MPU_Acc; + data.X = mpu6050.getAccX(); + data.Y = mpu6050.getAccY(); + data.Z = mpu6050.getAccZ(); + jSendNRF(&data, sizeof(data)); + }break; + case jCommand_MPU_Gyro:{ + mpuSendData data; + data.command = jCommand_MPU_Gyro; + data.X = mpu6050.getGyroX(); + data.Y = mpu6050.getGyroY(); + data.Z = mpu6050.getGyroZ(); + jSendNRF(&data, sizeof(data)); + }break; + case jCommand_MPU_Angle:{ + mpuSendData data; + data.command = jCommand_MPU_Angle; + data.X = mpu6050.getAngleX(); + data.Y = mpu6050.getAngleY(); + data.Z = mpu6050.getAngleZ(); + jSendNRF(&data, sizeof(data)); + }break; + } +} + +#else + +void initMPU(){} + +void MPULoop(){} + +void MPUradioTask(){ + mpuSendData data; + data.command = jCommand_MPU_fail; + jSendNRF(&data, sizeof(data)); +} + +#endif diff --git a/RCdata.h b/RCdata.h new file mode 100644 index 0000000..8d697ab --- /dev/null +++ b/RCdata.h @@ -0,0 +1,33 @@ +#define jType_RC 0 +//#define jCommand_GPS_location 0 + +#define NUM_ANALOG_channels 12 + +typedef struct{ + byte type; + byte command; + uint32_t btns; + int16_t analog[NUM_ANALOG_channels]; +}nrfRC; + +nrfRC RCdata; + +void initRCdata(){ + +} + +void RCdataLoop(){ + +} + +void RCdataradioTask(){ + memmove(&RCdata, &jRCbuff, sizeof(RCdata)); + onData(); +} + +bool RCgetBTN(byte i){ + return (RCdata.btns>>min(31,(int)i))&1; +} +int16_t RCgetAnalog(byte i){ + return RCdata.analog[min(NUM_ANALOG_channels-1,(int)i)]; +} diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..f262483 --- /dev/null +++ b/Readme.md @@ -0,0 +1,2 @@ +# DefaultReceiver +This software is designed to run on an esp32. It controls many sensors and communicates with the remote control in the background. \ No newline at end of file diff --git a/descriptionStruct.h b/descriptionStruct.h new file mode 100644 index 0000000..577b0a4 --- /dev/null +++ b/descriptionStruct.h @@ -0,0 +1,9 @@ +#ifndef _descriptionStruct_h_ +#define _descriptionStruct_h_ + +typedef struct { + byte use; //0-3 || 0-1 + char text[29]; //Text +}ChannelDesc; + +#endif diff --git a/juPadReceiver.h b/juPadReceiver.h new file mode 100644 index 0000000..181e332 --- /dev/null +++ b/juPadReceiver.h @@ -0,0 +1,193 @@ +#ifndef _juPadReceiver_h_ +#define _juPadReceiver_h_ + +#define maxLast 2500 + +typedef struct{ + byte type = 0xff; + uint64_t pipe; + byte channel; +}nrfMulticast; + +#ifndef myId + #error "myId is not defined" +#endif +#ifndef myChannel + #error "myChannel is not defined" +#endif + +#define multicastChannel 124 +#define multicastAddress 0xF0F0F0F0FF + +#define jChannel_0 13 +#define jChannel_1 12 +#define jChannel_2 14 +#define jChannel_3 27 +#define jChannel_4 26 +#define jChannel_5 25 +#define jChannel_6 33 +#define jChannel_7 32 +#define jChannel_8 15 + +#define jServo 1 +#define jhBridge 2 +#define jESC 3 +#define jDigital 4 + +#include +#include +#include "nRF24L01.h" +#include "RF24.h" +#include +Preferences preferences; + +void jSendNRF(const void* buf, uint8_t length); + +byte jRCbuff[32]; + +#include "MPU.h" +#include "RCdata.h" +#include "GNSS.h" +#include "COMP.h" +#include "BUTTONDesc.h" + +//3 (CE) 0 //4 (CSN) 4 //5 (SCK) 18 //6 (MOSI) 23 //7 (MISO) 19 +// CE CSN +RF24 radio(0,4); + +const uint64_t myPipe = 0xF0F0F0F000|myId ; + +//0 -> never, 1 -> connected, 2 -> lost/wait +byte jLastStatus = 0; +unsigned long jLast = 0; + +float avgRound = 10; +unsigned long lastRound = 0; +unsigned long delta = 10; + +void jSetup(){ + Serial.begin(115200); + Serial.print("Starting up ... "); + preferences.begin("data", false); + if(!radio.begin()){ + Serial.println("radio hardware is not responding!!"); + while (1) {} + } + radio.enableDynamicPayloads(); + radio.setRetries(5,15); + radio.setChannel(myChannel); + radio.openReadingPipe(0,myPipe); + radio.startListening(); + Wire.begin(); + initMPU(); + initGNSS(); + initCOMP(); + initRCdata(); + Serial.print("wait ... "); + delay(1000); + Serial.println("done"); + #ifdef debug + Serial.println("> debuging"); + #endif + lastRound = millis(); +} + +void jNoConn(){ + if(jLastStatus==1){ + onDisconnect(false); + jLastStatus=3; + } + if(random(25)==1){ +#ifdef debug + Serial.println("Multicast!"); +#endif + radio.stopListening(); + radio.setChannel(multicastChannel); + radio.openWritingPipe(multicastAddress); + nrfMulticast data; + data.pipe = myPipe; + data.channel = myChannel; + radio.write(&data, sizeof(data), true); + radio.setChannel(myChannel); + radio.startListening(); + } +} +void jConn(){ + if(jLastStatus!=1){ + onConnect(); + radio.openWritingPipe(myPipe); + radio.startListening(); + jLastStatus=1; + } +} + + +#ifdef debug +const String b16 = "0123456789abcdef"; + +String SensorDataBuffer=""; +#endif + +void receive(){ + if(radio.available()){ +#ifdef debug + Serial.println("Radio available!"); +#endif + uint8_t payloadSize = radio.getDynamicPayloadSize(); + if(payloadSize>=1){ + jLast = millis(); + radio.read( &jRCbuff, payloadSize ); +#ifdef debug + SensorDataBuffer = "data: "; + for (size_t i = 0; i < payloadSize; i++) { + SensorDataBuffer+=b16[(jRCbuff[i]>>4)&0xf]; + SensorDataBuffer+=b16[jRCbuff[i]&0xf]; + } + Serial.println(SensorDataBuffer); +#endif + switch (jRCbuff[0]) { + case jType_RC:{ + RCdataradioTask(); + }break; + case jType_S_MPU:{ + MPUradioTask(); + }break; + case jType_S_GNSS:{ + GNSSradioTask(); + }break; + case jType_S_COMP:{ + COMPradioTask(); + }break; + case jType_BUTTON_Desc:{ + BUTTON_DescradioTask(); + }break; + case jType_ANALOG_Desc:{ + ANALOG_DescradioTask(); + }break; + } + } + } +} + +void jLoop(){ + unsigned long now = millis(); + delta = now - lastRound; + lastRound = now; + avgRound = avgRound*0.9 + delta*0.1; + + MPULoop(); + GNSSLoop(); + COMPLoop(); + RCdataLoop(); + receive(); + if(millis()-jLast>maxLast)jNoConn(); + else jConn(); +} + +void jSendNRF(const void* buf, uint8_t length){ + radio.stopListening(); + radio.write( buf, length ); + radio.startListening(); +} + +#endif