![](/media/cache/profiles/profile_pic_for_github_less_than_1MB.jpg.50x50_q85.jpg)
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
Diff: main.cpp
- Revision:
- 42:911770814147
- Parent:
- 41:1381a49e019e
diff -r 1381a49e019e -r 911770814147 main.cpp --- a/main.cpp Wed Aug 01 08:32:21 2018 +0000 +++ b/main.cpp Wed Aug 15 04:06:09 2018 +0000 @@ -1,10 +1,4 @@ /* - * Copyright (c) 2018 HELIOS Software GmbH - * 30826 Garbsen (Hannover) Germany - * Licensed under the Apache License, Version 2.0); - */ - - /* * For Wiring Instructions, please visit the link below: * https://www.hackster.io/DevinAlex64/getting-started-with-the-max32620fthr-and-lora-f9d8dd\ */ @@ -18,6 +12,9 @@ //#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); @@ -102,43 +99,6 @@ void charger_Detect(); bool chrg_State_fn(); - - 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 @@ -239,7 +199,7 @@ * Motor Controller Instatiation and Related Functions **************************************************************************/ #if defined(TARGET_MAX32630FTHR) // Master Device: MAX32630FTHR BLE-to-LoRa Gateway - // There is no motor on this device. + // 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. */ @@ -255,7 +215,7 @@ // 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(0x61); + // 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 @@ -350,8 +310,6 @@ dprintf("Starting a simple LoRa PingPong"); - - /*************************************************************************** * Grid Eye Sensor: Non-Buffer Program Variables @@ -524,7 +482,8 @@ design_param.vcharge = 4200; // Battery Charge Voltage can be obtained from MAX77650 configuration design_param.rsense = 5; //5mOhms - int oper_f1, volt_mod_FG, status; + 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(); @@ -548,6 +507,10 @@ 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 @@ -715,74 +678,77 @@ pc.printf("Byte #%d is: %d\n", idx, max17055_u.curr_MAX17055_from_slave[idx]); } #endif - 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); - } - + 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); - //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=%duA \r\n",max17055_u.battery.avg_curr_FG); - 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.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(); } - - 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(); @@ -809,7 +775,7 @@ #endif /*************************************************************************** - * Fill Payload Buffer With Data From Sensors for LoRa Transmition + * 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); @@ -822,16 +788,14 @@ memcpy(&BufferTx[tx_idx_MAX77650], curr_MAX77650_to_master, size_of_MAX77650); #endif - - - + /*************************************************************************** * Lora Communications **************************************************************************/ SX1276PingPong(); /*************************************************************************** - * Fill Global Buffers With Data From Received Payload Buffer + * 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 @@ -851,15 +815,76 @@ #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 - if( memcmp(prev_ble_from_master, curr_ble_from_master, sizeof(curr_ble_from_master)) != 0 ) + 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 - - - + + #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