This is example code that can get you started with building your own IR vision robot that communicates over LoRa
Dependencies: Adafruit-MotorShield Adafruit-PWM-Servo-Driver Adafruit_GFX BufferedSerial MAX17055_EZconfig NEO-6m-GPS SX1276GenericLib USBDeviceHT max32630fthr max77650_charger_sample
Fork of MAX326xxFTHR_LoRa_Example_test by
main.cpp
- Committer:
- dev_alexander
- Date:
- 2018-08-15
- Revision:
- 42:911770814147
- Parent:
- 41:1381a49e019e
File content as of revision 42:911770814147:
/* * For Wiring Instructions, please visit the link below: * https://www.hackster.io/DevinAlex64/getting-started-with-the-max32620fthr-and-lora-f9d8dd\ */ /*************************************************************************** * Misc Instantiation **************************************************************************/\ #include "mbed.h" #include "main.h" #include "global_buffers.h" //#define DEBUG_GRID_EYE //#define DEBUG_MAX17055 #define RASPBERRY_PI #define NUM_TIMEOUTS_TO_STOP_ROBOT 15 #define OLED_FREQ 1000 DigitalOut myled(LED); Serial pc(USBTX, USBRX); I2C i2cBus0(P1_6, P1_7); I2C i2cBus1(P3_4, P3_5); I2C i2cBus2(P5_7, P6_0); /*************************************************************************** * MAX32630FTHR Instantiation **************************************************************************/ #if defined(TARGET_MAX32630FTHR) /* If the board that is compiled is the master device (BLE enabled MAX32630FTHR), * then it needs this library and needs to be configed in order for the device to * work with a 3.3volt output instead of a 1.8 volt output. * * This is only needed for the MAX32630FTHR. The MAX325620FTHR is exampt from this * additional setup in the main program. */ #include "max32630fthr.h" MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); #endif /*************************************************************************** * MAX32620FTHR Instantiation **************************************************************************/ #if defined(TARGET_MAX32620FTHR) #endif /*************************************************************************** * Grid Eye Sensor Instantiation **************************************************************************/ #include "GridEye.h" #if defined(TARGET_MAX32630FTHR) // Master Device: MAX32630FTHR BLE-to-LoRa Gateway /* No grid eye object needed. The function the master uses to convert the raw * data that is sent over from the slave deevice that contains the data from the * actual grid eye sensor is actually a function that is not part of the grid eye * class. this is due to the fact that the grid eye class requires n i2c bus to * be assigned to a phyiscal sensor. In this case, the library for the Grid Eye * sensor has a support function that is used to convert data that is aquired from * the grid eye sensor. So it is not supposed to be a class specific function. */ #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot GridEye gridEye(i2cBus0); #endif /*************************************************************************** * GPS Instantiation **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: MAX32630FTHR BLE-to-LoRa Gateway // No GPS module on the master device #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot #include "GPS.h" GPS gps(P0_1, P0_0, 115200); // (Tx, Rx, Baud rate) #endif /*************************************************************************** * MAX77650 Instatiation **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: MAX32630FTHR BLE-to-LoRa Gateway // No MAX77650 PMIC on this board #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot #include "max77650.h" // Definitions for running board off of battery #define POWER_HOLD_ON 1 #define POWER_HOLD_OFF 0 /* This is the pin that the MAX77650's Power Hold pin is connected to on MAX32620FTHR * Without programming it to POWER_HOLD_ON, the device cant be started off of battery * power alone. */ DigitalOut pw_Hold(P2_2, POWER_HOLD_ON); // Instatiate instance of the Simo Pimic MAX77650 simo_pmic(i2cBus2); // Battery Charger Interrupt InterruptIn simoIRQ(P2_3); void charger_Detect(); bool chrg_State_fn(); #endif /*************************************************************************** * MAX17055 Instatiation **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: MAX32630FTHR BLE-to-LoRa Gateway // No MAX77650 PMIC on this board #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot #include "max17055.h" MAX17055 fuelGauge(i2cBus2); MAX17055::platform_data design_param; #endif /*************************************************************************** * OLED Instatiation **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: MAX32630FTHR BLE-to-LoRa Gateway #include "Adafruit_SSD1306.h" #include "maxim_bitmap.h" Adafruit_SSD1306_I2c displayOled(i2cBus1); #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot /* Currently, there is no OLED display attached to the MAX32620, * so we are not compiling for it at the moment */ #endif /*************************************************************************** * BLE Instatiation and Related Functions **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: MAX32630FTHR BLE-to-LoRa Gateway #include "ble/BLE.h" //#include "ble/Gap.h" #include "UARTService_custom.h" #include <events/mbed_events.h> DigitalOut led2(LED2); UARTService *uart; #define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console; * it will have an impact on code-size and power consumption. */ #if NEED_CONSOLE_OUTPUT #define DEBUG(STR) { if (uart) uart->write(STR, strlen(STR)); } #define READ(STR) { if (uart) uart->read(STR, strlen(STR)); } #else #define DEBUG(...) /* nothing */ #endif /* #if NEED_CONSOLE_OUTPUT */ //Triggered when the robot is disconnected from the mobile app. void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { BLE &ble = BLE::Instance(); DEBUG("Disconnected!\n\r"); DEBUG("Restarting the advertising process\n\r"); ble.gap().startAdvertising(); } /* This pointer is needed to reference data in the main program when filling * with data from the BLE */ uint8_t * onDataWritten_curr_ble_to_slave; // Triggered when there is data written void onDataWritten(const GattWriteCallbackParams *params) { //LED1 will be off when button is pressed, and on when button is released. led2 = !led2; uint8_t button_state; uint8_t direction; /* If there is a valid data sent by the mobile app */ if ((uart != NULL) && (params->handle == uart ->getTXCharacteristicHandle())) { const uint8_t *packet = params->data; button_state = packet[3]; direction = packet[2]; // make parameter to send over Lora onDataWritten_curr_ble_to_slave[0] = direction; onDataWritten_curr_ble_to_slave[1] = button_state; //dprintf("direction: %d\n", direction); //dprintf("button_state: %d\n", button_state); } } #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot // No BLE chip on the MAX32620FTHR so this is not needed #endif /*************************************************************************** * Motor Controller Instatiation and Related Functions **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: MAX32630FTHR BLE-to-LoRa Gateway // There is no motor controller on this device. #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot /* This is a port of a library that was developed by Adafruit for the Arduino. * This port was done by mbed user syundo0730. */ #include "Adafruit_MotorShield.h" #include "Adafruit_PWMServoDriver.h" // These are the defined speeds that are selected out of the number range (0, 255). #define MOTOR_OFF 0 #define MOTOR_FORWARD 150 #define MOTOR_BACKWARD 150 #define MOTOR_TURN 100 // Create the motor shield object with the default I2C address Adafruit_MotorShield AFMS = Adafruit_MotorShield(P3_4, P3_5, 0x60 << 1); // You have to shift it over by one due to how mbed does its I2C Addressing. // Or, create it with a different I2C address (say for stacking) // Adafruit_MotorShield AFMS = Adafruit_MotorShield(P3_4, P3_5, 0x61 << 1); // Select which 'port' M1, M2, M3 or M4. In this case, M1 Adafruit_DCMotor *rightMotor = AFMS.getMotor(1); // You can also make another motor on port M4 Adafruit_DCMotor *leftMotor = AFMS.getMotor(4); void MotorController(uint8_t (BLE_data_server)[2]) { uint8_t button_state; uint8_t direction; /*Set up constants for direction of motion */ const char FRONT = '5'; const char BACK = '6'; const char LEFT = '7'; const char RIGHT = '8'; /*Set up constants for button state */ const char PRESSED = '1'; const char RELEASED = '0'; button_state = BLE_data_server[1]; direction = BLE_data_server[0]; switch (button_state) { case PRESSED: switch (direction) { case FRONT: rightMotor->run(FORWARD); leftMotor->run(FORWARD); rightMotor->setSpeed(MOTOR_FORWARD); leftMotor->setSpeed(MOTOR_FORWARD); break; case BACK: rightMotor->run(BACKWARD); leftMotor->run(BACKWARD); rightMotor->setSpeed(MOTOR_BACKWARD); leftMotor->setSpeed(MOTOR_BACKWARD); break; case LEFT: rightMotor->run(FORWARD); leftMotor->run(BACKWARD); rightMotor->setSpeed(MOTOR_TURN); leftMotor->setSpeed(MOTOR_TURN); break; case RIGHT: rightMotor->run(BACKWARD); leftMotor->run(FORWARD); rightMotor->setSpeed(MOTOR_TURN); leftMotor->setSpeed(MOTOR_TURN); break; } break; case RELEASED: rightMotor->setSpeed(MOTOR_OFF); leftMotor->setSpeed(MOTOR_OFF); break; } } #endif int main() { /* Setup begins here: */ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway dprintf("MAX32630FTHR: Master"); #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot dprintf("MAX32620FTHR: Slave"); #endif #if defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot //Set Power Hold High for battery operation MAX77650 on MAX32620FTHR pw_Hold = POWER_HOLD_ON; #endif /* * inits the Serial or USBSerial when available (230400 baud). * If the serial uart is not is not connected it swiches to USB Serial * blinking LED means USBSerial detected, waiting for a connect. * It waits up to 30 seconds for a USB terminal connections */ InitSerial(30*1000, &myled); dprintf("Welcome to the SX1276GenericLib"); dprintf("Starting a simple LoRa PingPong"); /*************************************************************************** * Grid Eye Sensor: Non-Buffer Program Variables **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway int frame_idx = 0; #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot #if defined(DEBUG_GRID_EYE_SLAVE) int frame_idx = 0; #endif #endif /*************************************************************************** * Combined Payload Buffers for LoRa Communications **************************************************************************/ uint8_t BufferTx[BufferSizeTx]; uint8_t BufferRx[BufferSizeRx]; /*************************************************************************** * Identification Buffers **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway uint8_t ID_of_slave[size_signature]; #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot uint8_t ID_of_master[size_signature]; #endif /*************************************************************************** * BLE Data Buffers **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway uint8_t curr_ble_to_slave[size_of_ble]; #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot uint8_t curr_ble_from_master[size_of_ble]; uint8_t prev_ble_from_master[size_of_ble]; #endif /*************************************************************************** * Grid Eye Sensor Data Buffers **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway char curr_raw_frame_from_slave[size_of_grid_eye]; char prev_raw_frame_from_slave[size_of_grid_eye]; int16_t conv_frame_from_slave[64]; #elif defined(TARGET_MAX32620FTHR) // Client Device: LoRa Controlled Robot char curr_raw_frame_to_master[size_of_grid_eye]; char prev_raw_frame_to_master[size_of_grid_eye]; int16_t conv_frame_to_master[64]; #endif /*************************************************************************** * GPS Data Buffers **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway uint8_t curr_gps_from_slave[size_of_gps]; uint8_t prev_gps_from_slave[size_of_gps]; #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot uint8_t curr_gps_to_master[size_of_gps]; #endif /*************************************************************************** * MAX17055 Data Buffers **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway union max17055_u { uint8_t curr_MAX17055_from_slave[size_of_MAX17055]; struct battery { uint8_t soc_FG; // in Battery Percent uint8_t avg_soc_FG; // in Battery Percent float tte_FG; // in seconds float ttf_FG; // in seconds int vcell_FG; // in 78.125uV per bit int curr_FG; // in uAmps int avg_curr_FG; // in uAmps } battery; } max17055_u; uint8_t prev_MAX17055_from_slave[size_of_MAX17055]; #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot union max17055_u { uint8_t curr_MAX17055_to_master[size_of_MAX17055]; struct battery { uint8_t soc_FG; // in Battery Percent uint8_t avg_soc_FG; // in Battery Percent float tte_FG; // in seconds float ttf_FG; // in seconds int vcell_FG; // in 78.125uV per bit int curr_FG; // in uAmps int avg_curr_FG; // in uAmps } battery; } max17055_u; #endif /*************************************************************************** * MAX77650 Data Buffers **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway uint8_t curr_MAX77650_from_slave[size_of_MAX77650]; uint8_t prev_MAX77650_from_slave[size_of_MAX77650]; bool chrg_status = false;; //True = ON False = OFF #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot uint8_t curr_MAX77650_to_master[size_of_MAX77650]; bool chrg_status = false; //True = ON False = OFF #endif /*************************************************************************** * Finish Setting up LoRa Radios: This passes in pointers to Buffers to send **************************************************************************/ SX1276PingPongSetup(BufferTx, BufferRx); /*************************************************************************** * Finish Setting up BLE Radio on the MAX32630FTHR: Only on the Master Device **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway BLE &ble = BLE::Instance(); /* Create alias for the BLE data to be saved in function above that * writes data to this buffer when function onDataWritten is called */ onDataWritten_curr_ble_to_slave = curr_ble_to_slave; /* Initialize BLE */ ble.init(); ble.gap().onDisconnection(disconnectionCallback); ble.gattServer().onDataWritten(onDataWritten); uart = new UARTService(ble); /* setup advertising */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)"BLE UART", sizeof("BLE UART") - 1); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); ble.gap().setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ ble.gap().startAdvertising(); #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot /* There is no BLE device that is integrated into the MAX32620FTHR. Also * Also this program is meant to use the BLE gateway on the MAX32630FTHR */ #endif /*************************************************************************** * Finish Setting up the MAX77650 on the MAX32620FTHR: Only on the Slave Device **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway // No MAX77650 on the MAX32630FTHR #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot //Set Power Hold High for battery operation MAX77650 on MAX32620FTHR pw_Hold = POWER_HOLD_ON; //Simo Pmic MAX77650 init simo_pmic.initCharger(); simoIRQ.fall( &charger_Detect ); simo_pmic.enCharger(); #endif /*************************************************************************** * Finish Setting up the MAX17650 on the MAX32620FTHR: Only on the Slave Device **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway // No MAX17055 on the MAX32630FTHR #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot //rsense 5mOhm for MAX32620FTHR design_param.designcap = 2200; //Design Battery Capacity mAh design_param.ichgterm = 0x0016; // Charge Termination Current for the Battery design_param.vempty = 0x9B00; // Battery Empty Voltage design_param.vcharge = 4200; // Battery Charge Voltage can be obtained from MAX77650 configuration design_param.rsense = 5; //5mOhms int oper_f1, volt_mod_FG; int status; // stores return value of the status of setting up the MAX17055 //serial.printf("Test Init and Temp Functions \r\n"); //status = fuelGauge.forcedExitHyberMode(); status = fuelGauge.init(design_param); pc.printf("Init FuelGauge Function Status= %X \r\n",status); #endif /*************************************************************************** * Finish Setting up the SSD1306 OLED on the MAX32630FTHR: Only on the Master Device **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway displayOled.setTextColor(1); displayOled.setTextSize(1); displayOled.setTextWrap(false); displayOled.clearDisplay(); displayOled.printf("%ux%u Please Check Connection to Robot!!\r\n", displayOled.width(), displayOled.height()); //displayOled.drawBitmap(0,0,maximLarge,128,32,1); displayOled.display(); displayOled.display(); wait(1.0); displayOled.startscrollright(0x00, 0x0F); uint32_t OLED_COUNT; #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot // No oled on the MAX32620FTHR #endif /*************************************************************************** * Finish Setting up the motor controller on the MAX32620FTHR: Only on the Slave Device **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway // No setup on the master device #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot AFMS.begin(); // create with the default frequency 1.6KHz //AFMS.begin(1000); // OR with a different frequency, say 1KHz // Set the speed to start, from 0 (off) to 255 (max speed) rightMotor->setSpeed(150); rightMotor->run(FORWARD); // turn on motor rightMotor->run(RELEASE); leftMotor->setSpeed(150); leftMotor->run(FORWARD); // turn on motor leftMotor->run(RELEASE); #endif while(1) { /*************************************************************************** * BLE Radio Data **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway ble.waitForEvent(); #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot memcpy(curr_ble_from_master, prev_ble_from_master, sizeof(curr_ble_from_master)); #endif /*************************************************************************** * Grid Eye Sensor **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway // Check to see if the contents of the previous scan are the same. If they are different then continue with converting #if defined(RASPBERRY_PI) if( memcmp(prev_raw_frame_from_slave, curr_raw_frame_from_slave, sizeof(curr_raw_frame_from_slave)) != 0 ) { char grid_eye_msg[130]; grid_eye_msg[0]=0x55; grid_eye_msg[1]=0xaa; for (int idx = 0; idx < 128; idx++) grid_eye_msg[idx+2] = curr_raw_frame_from_slave[idx]; //pc.printf(grid_eye_msg); for (int idx = 0; idx < 130; idx++) pc.putc(grid_eye_msg[idx]); pc.printf("\r\n"); // seperate the lines } #endif #if defined(DEBUG_GRID_EYE) if( memcmp(prev_raw_frame_from_slave, curr_raw_frame_from_slave, sizeof(curr_raw_frame_from_slave)) != 0 ) { // Convert raw data sent from slave to a 16 bit integer array by calling this convRaw8x8Data2Point25degC(curr_raw_frame_from_slave, conv_frame_from_slave); // Next Print off the Converted data pc.printf("\r\nFrame %d data: \r\n", frame_idx); uint8_t idx; float pixel_data; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { idx = y*8 + x; pixel_data = ((float)conv_frame_from_slave[idx])/4.0; pc.printf("%.2f \t", pixel_data); } pc.printf("\r\n\r\n"); } pc.printf("\r\n"); // Increment frame counter frame_idx = frame_idx +1; } #endif /* Next copy in data received from current data into buffer used for * comparison next time the memcmp above is called. This prevents the * program from converting the same raw data aquired by the grid eye * sensor on the slave device to the floating point array with the * 0.25 degrees celsius precision level when there is not new data. */ memcpy(prev_raw_frame_from_slave, curr_raw_frame_from_slave, sizeof(curr_raw_frame_from_slave)); #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot // Aquire raw data about 8x8 frame from the grid eye sensor in this function call gridEye.getRaw8x8FrameData(curr_raw_frame_to_master); #if defined(RASPBERRY_PI) if( memcmp(prev_raw_frame_to_master, curr_raw_frame_to_master, sizeof(curr_raw_frame_to_master)) != 0 ) { char grid_eye_msg[130]; grid_eye_msg[0]=0x55; grid_eye_msg[1]=0xaa; for (int idx = 0; idx < 128; idx++) grid_eye_msg[idx+2] = curr_raw_frame_to_master[idx]; //pc.printf(grid_eye_msg); for (int idx = 0; idx < 130; idx++) pc.putc(grid_eye_msg[idx]); pc.printf("\r\n"); // seperate the lines } #endif #if defined(DEBUG_GRID_EYE) if( memcmp(prev_raw_frame_to_master, curr_raw_frame_to_master, sizeof(curr_raw_frame_to_master)) != 0 ) { // Convert raw data sent from slave to a 16 bit integer array by calling this convRaw8x8Data2Point25degC(curr_raw_frame_to_master, conv_frame_to_master); // Next Print off the Converted data pc.printf("\r\nFrame %d data: \r\n", frame_idx); uint8_t idx; float pixel_data; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { idx = y*8 + x; pixel_data = ((float)conv_frame_to_master[idx])/4.0; pc.printf("%.2f \t", pixel_data); } pc.printf("\r\n\r\n"); } pc.printf("\r\n"); // Increment frame counter frame_idx = frame_idx +1; } #endif memcpy(prev_raw_frame_to_master, curr_raw_frame_to_master, sizeof(curr_raw_frame_to_master)); #endif /*************************************************************************** * GPS Sensor **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway // No gps sensor is applied #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot // The testing hasnt been done yet for the GPS Module. Will do this when more parts come in. /* if(gps.sample()){ pc.printf("%f\t%c\t%f\t%c\t%f\t%f\t%f\n\r",gps.longitude, gps.ns,gps.latitude,gps.ew, gps.alt, gps.geoid, gps.time); pc.printf("%d:%d:%d",gps.hour,gps.minute,gps.seconed); } */ #endif /*************************************************************************** * MAX17055 Fuel Gauge Sensor **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway // Process the soc to see if the oled display needs to be updated or not. #if defined(DEBUG_MAX17055) pc.printf("soc_FG :%d\n" ,max17055_u.battery.soc_FG); pc.printf("avg_soc_FG :%d\n" ,max17055_u.battery.avg_soc_FG); pc.printf("tte_FG :%d\n" ,max17055_u.battery.tte_FG); pc.printf("ttf_FG :%d\n" ,max17055_u.battery.ttf_FG); pc.printf("vcell_FG :%d\n" ,max17055_u.battery.vcell_FG); pc.printf("curr_FG :%d\n" ,max17055_u.battery.curr_FG); pc.printf("avg_curr_FG :%d\n" ,max17055_u.battery.avg_curr_FG); for (int idx = 0; idx < size_of_MAX17055; idx++) { pc.printf("Byte #%d is: %d\n", idx, max17055_u.curr_MAX17055_from_slave[idx]); } #endif OLED_COUNT = OLED_COUNT + 1; if( OLED_COUNT % OLED_FREQ == 0) { if( memcmp(prev_MAX17055_from_slave, curr_MAX17055_from_slave, sizeof(curr_MAX17055_from_slave)) != 0 ) { // Stop the scrolling to allow for a static image to be displayed on OLED displayOled.stopscroll(); displayOled.clearDisplay(); // if ( chrg_status == false){ // if (max17055_u.battery.soc_FG >= 89) // displayOled.drawBitmap(96,0,battFull,32,16,1); // else if (max17055_u.battery.soc_FG >= 65 && max17055_u.battery.soc_FG < 89) // displayOled.drawBitmap(96,0,batt75,32,16,1); // else if (max17055_u.battery.soc_FG >= 45 && max17055_u.battery.soc_FG < 65) // displayOled.drawBitmap(96,0,batt50,32,16,1); // else if (max17055_u.battery.soc_FG >= 20 && max17055_u.battery.soc_FG < 45) // displayOled.drawBitmap(96,0,batt25,32,16,1); // else // displayOled.drawBitmap(96,0,battEmpty,32,16,1); // } if (chrg_status == true){ displayOled.drawBitmap(96,0,battChrging,32,16,1); } //serial.printf("Time to Empty= %dsec \r\n",tte_FG); int tte_minutes = (max17055_u.battery.tte_FG/60); int ttf_minutes = (max17055_u.battery.tte_FG/60); //serial.printf("Time to Empty= %dhours \r\n",tte_FG); //serial.printf("Temp Function Status= %X \r\n",status); //wait(1); //serial.printf("SOC = %d %% \r\n",soc_FG); //serial.printf("Temp Function Status= %X \r\n",status); //serial.printf("Current = %d uamp \r\n",curr_FG); // pc.printf("Voltage = %d uvolts \r\n",max17055_u.battery.vcell_FG); int oper_f1 = max17055_u.battery.vcell_FG /1000000; int volt_mod_FG = (max17055_u.battery.vcell_FG % 1000000)/1000; // pc.printf("Voltage = %d V \r\n",max17055_u.battery.vcell_FG); // pc.printf("Voltage = %d V \r\n",oper_f1); displayOled.setTextCursor(0,0); displayOled.setTextColor(1); displayOled.setTextSize(1); //displayOled.setTextWrap(true); displayOled.printf("MAX17055"); displayOled.setTextCursor(0,8); displayOled.printf("SOC = %d%% \r\n",max17055_u.battery.avg_soc_FG); displayOled.setTextCursor(0,16); if (chrg_status == true){ displayOled.printf("TTF = %dmins \r\n",tte_minutes); }else displayOled.printf("TTE = %dmins \r\n",tte_minutes); displayOled.setTextCursor(0,24); // displayOled.printf("I=%dmA \r\n",max17055_u.battery.avg_curr_FG/1000); // displayOled.setTextCursor(65,24); if (volt_mod_FG > 99){ displayOled.printf("V=%d.%dV \r\n",oper_f1,volt_mod_FG); }else if (volt_mod_FG < 100){ displayOled.printf("V=%d.0%dV \r\n",oper_f1,volt_mod_FG); } displayOled.display(); displayOled.display(); } } #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot max17055_u.battery.soc_FG = fuelGauge.get_SOC(); max17055_u.battery.avg_soc_FG = fuelGauge.get_atAvSOC(); max17055_u.battery.tte_FG = fuelGauge.get_TTE(); max17055_u.battery.ttf_FG = fuelGauge.get_TTF(); max17055_u.battery.vcell_FG = fuelGauge.get_Vcell(); max17055_u.battery.curr_FG = fuelGauge.get_Current(design_param); max17055_u.battery.avg_curr_FG = fuelGauge.get_AvgCurrent(design_param); #if defined(DEBUG_MAX17055) pc.printf("soc_FG :%d\n" ,max17055_u.battery.soc_FG); pc.printf("avg_soc_FG :%d\n" ,max17055_u.battery.avg_soc_FG); pc.printf("tte_FG :%d\n" ,max17055_u.battery.tte_FG); pc.printf("ttf_FG :%d\n" ,max17055_u.battery.ttf_FG); pc.printf("vcell_FG :%d\n" ,max17055_u.battery.vcell_FG); pc.printf("curr_FG :%d\n" ,max17055_u.battery.curr_FG); pc.printf("avg_curr_FG :%d\n" ,max17055_u.battery.avg_curr_FG); for (int idx = 0; idx < size_of_MAX17055; idx++) { pc.printf("Byte #%d is: %d\n", idx, max17055_u.curr_MAX17055_to_master[idx]); } #endif #endif /*************************************************************************** * Fill Payload Buffer With Data From Main Program Buffers for next LoRa Transmition **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway memcpy(&BufferTx[tx_idx_signature], PingMsg, size_signature); memcpy(&BufferTx[tx_idx_ble], curr_ble_to_slave, size_of_ble); #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot memcpy(&BufferTx[tx_idx_signature], PongMsg, size_signature); memcpy(&BufferTx[tx_idx_grid_eye], curr_raw_frame_to_master, size_of_grid_eye); memcpy(&BufferTx[tx_idx_gps], curr_gps_to_master, size_of_gps); memcpy(&BufferTx[tx_idx_MAX17055], max17055_u.curr_MAX17055_to_master, size_of_MAX17055); memcpy(&BufferTx[tx_idx_MAX77650], curr_MAX77650_to_master, size_of_MAX77650); #endif /*************************************************************************** * Lora Communications **************************************************************************/ SX1276PingPong(); /*************************************************************************** * Fill Main Program Buffers With Data From Received Payload Buffer **************************************************************************/ /* The master and slave devices will have different requirements for offloading payload */ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway memcpy(ID_of_slave, &BufferRx[rx_idx_signature], size_signature); memcpy(curr_raw_frame_from_slave, &BufferRx[rx_idx_grid_eye], size_of_grid_eye); memcpy(curr_gps_from_slave, &BufferRx[rx_idx_gps], size_of_gps); memcpy(max17055_u.curr_MAX17055_from_slave, &BufferRx[rx_idx_MAX17055], size_of_MAX17055); memcpy(curr_MAX77650_from_slave, &BufferRx[rx_idx_MAX77650], size_of_MAX77650); #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot memcpy(ID_of_master, &BufferRx[rx_idx_signature], size_signature); memcpy(curr_ble_from_master, &BufferRx[rx_idx_ble], size_of_ble); #endif /*************************************************************************** * Motor Controller controlls go here **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway // No motor controller on master #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot /* This helps prevent devices such as robots that are connected over * LoRa from not receiving a stop message. This can help prevent * situations where a robot received a command to move in a dirrection * but then moved to an area where it cant reliably receive communications. * This situation would prevent a robot from stopping if it cant receive * communications. So this is used to stop the current movement if the * robot is still moving after x amount of RxTimeouts have happened * in the LoRa communications. */ if (numOfRxTimeouts() >= NUM_TIMEOUTS_TO_STOP_ROBOT) { uint8_t simulate_release_button[2]; simulate_release_button[0] = curr_ble_from_master[0]; simulate_release_button[1] = 0; MotorController(simulate_release_button); } // Check to see if the contents of the previous ble sdata received are the same. If they are different then change motor controllers registers else if( memcmp(prev_ble_from_master, curr_ble_from_master, sizeof(curr_ble_from_master)) != 0 ) { MotorController(curr_ble_from_master); memcpy(prev_ble_from_master, curr_ble_from_master, sizeof(curr_ble_from_master)); } #endif } } /*************************************************************************** * MAX77650 Additional Functions **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: MAX32630FTHR BLE-to-LoRa Gateway // No MAX77650 PMIC on this board #elif defined(TARGET_MAX32620FTHR) // Slave Device: LoRa Controlled Robot void charger_Detect() { uint8_t int_chr_value,temp, int_chr_MASK = 0x04; int status; pc.printf("Charger Detected \n"); status = simo_pmic.readReg(MAX77650::INT_CHG, int_chr_value); pc.printf("INT_CHR val= %X \n", int_chr_value); if (status == 1){ temp = int_chr_value & int_chr_MASK; pc.printf("INT_CHR anded= %X \n", temp); if (temp == 4) { pc.printf("enable charger \n"); simo_pmic.enCharger(); } } } bool chrg_State_fn() { uint8_t status_chr_value,temp, chr_status_MASK = 0x02; int status; pc.printf("Charger State \n"); status = simo_pmic.readReg(MAX77650::STAT_CHG_B, status_chr_value); pc.printf("STAR_CHG_B val= %X \n", status_chr_value); if (status == 1) { temp = status_chr_value & chr_status_MASK; pc.printf("STAR_CHG_B val= %X \n", temp); if (temp == 2){ return true; } return false; } return false; } #endif