LP Long Distance IR Vision Robot
Dependencies: max77650_charger_sample BufferedSerial SX1276GenericLib Adafruit-MotorShield NEO-6m-GPS MAX17055_EZconfig Adafruit_GFX USBDeviceHT Adafruit-PWM-Servo-Driver
Revision 23:f74a50977593, committed 2018-07-18
- Comitter:
- dev_alexander
- Date:
- Wed Jul 18 18:52:30 2018 +0000
- Parent:
- 22:abca9d17d13d
- Child:
- 24:e8d03912f303
- Commit message:
- I added file global_buffers.h and also reworked a portion of the main.cpp to adjust to the new method of using global buffers defined in a different file.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GridEye/GridEye.cpp Wed Jul 18 18:52:30 2018 +0000 @@ -0,0 +1,238 @@ +/********************************************************************** +* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +**********************************************************************/ + + +#include "GridEye/GridEye.h" + + + +GridEye::GridEye(I2C &i2c) +: m_i2cBus(i2c) +{ +} + + + + +//********************************************************************* +int8_t GridEye::gridEyeReadReg(GridEyeRegister reg_addr, int num_bytes, char * data_buf) +{ + int8_t result; + char read_pointer[1]; + read_pointer[0] = reg_addr; + + result = GridEye::m_i2cBus.write(I2C_W_ADRS, read_pointer, 1); + if (result == I2C_WR_SUCCESS) + { + result = GridEye::m_i2cBus.read(I2C_R_ADRS, data_buf , num_bytes, false); + if (result == I2C_WR_SUCCESS) + return result; + } + return I2C_WR_ERROR; +} + + + +//********************************************************************* +int8_t GridEye::gridEyeWriteReg(GridEyeRegister reg_addr, int num_bytes, char * data_buf) +{ + int8_t result; + int num_indices = num_bytes + 1; + char write_buffer[num_indices]; + + //construct write buffer with the address followed by the data to be written + write_buffer[0] = reg_addr; + for (int idx=0; idx<num_bytes; idx++) + write_buffer[idx+1] = data_buf[idx]; + + result = GridEye::m_i2cBus.write(I2C_W_ADRS, write_buffer, num_indices); + if (result == I2C_WR_SUCCESS) + return result; + + //else, return -1 + return I2C_WR_ERROR; +} + + +//********************************************************************* +int8_t GridEye::getThermistorTemperature(int16_t & therm_temp) +{ + int8_t result; + char data[2]; + + result = this->gridEyeReadReg(GridEye::THERMISTOR_LOW, 2, data); + + if(result == I2C_WR_SUCCESS) + { + convSingleRawTempData2Int(data, therm_temp); + return therm_temp; + } + return I2C_WR_ERROR; +} + + +//********************************************************************* +int8_t GridEye::getPixelTemperature(uint8_t pixel_addr, int16_t & pixel_temp) +{ + int8_t result; + char data[2]; + + result = this->gridEyeReadReg((GridEyeRegister) pixel_addr, 2, data); + if(result == I2C_WR_SUCCESS) + { + convSingleRawTempData2Int(data, pixel_temp); + return pixel_temp; + } + return I2C_WR_ERROR; +} + + +//********************************************************************* +int8_t GridEye::getRaw8x8FrameData(char * raw_frame_data) +{ + int8_t result; + result = gridEyeReadReg((GridEyeRegister) GridEye::PIXEL_BASE_ADRS, 128, raw_frame_data); + return result; +} + + +//********************************************************************* +int8_t GridEye::setOperatingMode(GridEye::OperatingMode mode) +{ + int8_t result; + char set_mode[1]; + set_mode[0] = (char)mode; + result = this->gridEyeWriteReg(GridEye::OPERATING_MODE, 1, set_mode); + if (result == I2C_WR_SUCCESS) + return result; + return I2C_WR_ERROR; +} + +//********************************************************************* +int8_t GridEye::setFrameRate(GridEye::FrameRate rate) +{ + int8_t result; + char set_rate[1]; + set_rate[0] = (char)rate; + result = this->gridEyeWriteReg(GridEye::FRAME_RATE, 1, set_rate); + if (result == I2C_WR_SUCCESS) + return result; + return I2C_WR_ERROR; +} + +//********************************************************************* +void convSingleRawTempData2Int(char * data, int16_t & pixel_temp) +{ + int8_t upper_byte = data[1]; + int8_t lower_byte = data[0]; + int16_t upper_byte_mask = 0x0F00; + int16_t sign_bit = 0x0200; + int16_t finish_neg_val = 0xFC00; + int16_t pixel; + + //construct the pixel based off the 12 bit signed data + pixel = (upper_byte << 8); + pixel &= upper_byte_mask; + pixel |= lower_byte; + + //shift it over to gain integer value of the pixel + pixel = pixel >> 2; + + //if negative, properly convert to 16 bit int format to represent 2's compliment + if (pixel&sign_bit) + pixel |= finish_neg_val; + + //set the coresponding pixel to be in the passed in array + pixel_temp = pixel; +} + +//********************************************************************* +void convRaw8x8Data2Int(char * data, int16_t * frame_temp) { + int idx = 0; + int8_t upper_byte; + int8_t lower_byte; + int16_t upper_byte_mask = 0x0F00; + int16_t sign_bit = 0x0200; + int16_t finish_neg_val = 0xFC00; + int16_t pixel; + + for (idx=0; idx<64; idx++) + { + //construct the pixel based off the 12 bit signed data + upper_byte = data[idx*2+1]; + lower_byte = data[idx*2+0]; + pixel = (upper_byte << 8); + pixel &= upper_byte_mask; + pixel |= lower_byte; + + //shift it over to gain integer value of the pixel + pixel = pixel >> 2; + + //if negative, properly convert to 16 bit int format to represent 2's compliment + if (pixel&sign_bit) + pixel |= finish_neg_val; + + //set the coresponding pixel to be in the passed in array + frame_temp[idx] = pixel; + } +} + +//********************************************************************* +void convRaw8x8Data2Point25degC(char * data, int16_t * frame_temp) +{ + int idx = 0; + int8_t upper_byte; + int8_t lower_byte; + int16_t upper_byte_mask = 0x0F00; + int16_t sign_bit = 0x0800; + int16_t finish_neg_val = 0xF000; + int16_t pixel; + + for (idx=0; idx<64; idx++) + { + //construct the pixel based off the 12 bit signed data + upper_byte = data[idx*2+1]; + lower_byte = data[idx*2+0]; + pixel = (upper_byte << 8); + pixel &= upper_byte_mask; + pixel |= lower_byte; + + //no shift needed since we would lose the two lsb that give 0.25*C precision + + //if negative, properly convert to 16 bit int format to represent 2's compliment + if (pixel & sign_bit) + pixel |= finish_neg_val; + + //set the coresponding pixel to be in the passed in array + frame_temp[idx] = pixel; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GridEye/GridEye.h Wed Jul 18 18:52:30 2018 +0000 @@ -0,0 +1,236 @@ +/********************************************************************** +* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +**********************************************************************/ + + +#ifndef GRIDEYE_H +#define GRIDEYE_H + + +#include "mbed.h" + +#define I2C_WR_SUCCESS 0 +#define I2C_WR_ERROR -1 + +/** +* @brief Object for interfacing to MAXREFDES131# +* +* @details MAXREFDES131# combines the DS28E17 1-wire to I2C bridge +* with the Panasonic AMG8833 GridEye sensor. The reference design also +* includes a DS2413 2ch open drain switch for controlling the MAX4717 +* dual SPDT analog switch. The DS28E17 and AMG8833 are connected to +* the 1-wire bus via COM2 of the MAX4717 and COM1 is used for +* daisy-chaining additional modules. Disconnecting the DS28E17/AMG8833 +* from the main 1-wire branch puts both devices to sleep and reduces current +* consumption from 10mA to a couple hundred uA. +*/ +class GridEye +{ + private: + I2C &m_i2cBus; + + static const uint8_t I2C_ADRS = 0x68; + static const uint8_t I2C_W_ADRS = (uint8_t)((0x68)<<1); + static const uint8_t I2C_R_ADRS = (uint8_t)((0x68)<<1)+1; + + + public: + + /** + * @brief GridEye operating modes + */ + enum OperatingMode + { + NormalMode = 0x00, + SleepMode = 0x10, + StandBy60sec = 0x20, + StandBy10sec = 0x21 + }; + + /** + * @brief GridEye operating modes + */ + enum FrameRate + { + TenFPS = 0x00, + OneFPS = 0x01 + }; + + /** + * @brief AMG8833 register map + */ + enum GridEyeRegister + { + OPERATING_MODE, + RESET, + FRAME_RATE, + INT_CONTROL, + STATUS, + STATUS_CLEAR, + AVERAGE = 7, + INT_LEVEL_1, + INT_LEVEL_2, + INT_LEVEL_3, + INT_LEVEL_4, + INT_LEVEL_5, + INT_LEVEL_6, + THERMISTOR_LOW, + THERMISTOR_HI, + INT_1, + INT_2, + INT_3, + INT_4, + INT_5, + INT_6, + INT_7, + INT_8, + PIXEL_BASE_ADRS = 0x80 + }; + +/* static const uint8_t DS2413_FAMILY_CODE = 0x3A; + + static const uint8_t DS28E17_FAMILY_CODE = 0x19; +*/ + /** + * @brief GridEye Constructor + * + * @details setI2CBridge() by passing in I2C parameter + * + * @param[in] selector - MultidropRomIterator object that + * encapsulates ROM fxs of 1-wire protocol + */ + GridEye(I2C &i2c); + + + + + /** + * @brief gridEyeWriteReg + * + * @details Provides read/write access to the AMG8833 + * + * On Entry: + * @param[in] regAdrs - AMG8833 register to start reading/writting + * from/to + * @param[in] numBytes - Number of bytes of data to write + * @param[in] dataBuf - Pointer to data buffer for storing data in + * on read, or data to be written on write + * + * On Exit: + * + * @return CmdResult - return 0 if the operation was sucessful, return -1 if unsucessful + */ + int8_t gridEyeWriteReg(GridEyeRegister reg_addr, int num_bytes, char * data_buf); + + /** + * @brief gridEyeReadReg + * + * @details Provides read/write access to the AMG8833 + * + * On Entry: + * @param[in] regAdrs - AMG8833 register to start reading/writting + * from/to + * @param[in] numBytes - Number of bytes to read + * @param[in] dataBuf - Pointer to data buffer for storing data in + * on read, or data to be written on write + * + * On Exit: + * @param[out] dataBuf - Read data on read operation + * + * @return CmdResult - return 0 if the operation was sucessful, return -1 if unsucessful + */ + int8_t gridEyeReadReg(GridEyeRegister reg_addr, int num_bytes, char * data_buf); + + + /** + * @brief getThermistorTemperature + * + * @details Gets internal thermistor temperature + * + * On Entry: + * @param[in] thermTemp - reference to int16_t var that will be overwritten + * with thermistor data + * + * On Exit: + * @param[out] thermTemp - thermistor data + * + * @return CmdResult - result of operation + */ + int8_t getThermistorTemperature(int16_t & therm_temp); + + + /** + * @brief getPixelTemperature + * + * @details Gets individual pixel temperature + * + * On Entry: + * @param[in] pixelAdrs - address of pixel to read + * @param[in] pixelTemp - reference to int16_t var that will be overwritten + * with thermistor data + * + * On Exit: + * @param[out] pixelTemp - pixel data + * + * @return CmdResult - result of operation + */ + int8_t getPixelTemperature(uint8_t pixel_addr, int16_t & pixel_temp); + + /** + * @brief getRaw8x8FrameData + * + * @details Gets pixel frame(64 pixels in 128 bytes) temperature + * + * On Entry: + * @param[in] raw_frame_data - buffer to hold 2 bytes data per pixel + * + * On Exit: + * @param[out] raw_frame_data - pixel data not yet formatted + * + * @return int8_t - result of operation, 0 on success, -1 on failure + */ + int8_t getRaw8x8FrameData(char * raw_frame_data); + + + int8_t setOperatingMode(GridEye::OperatingMode mode); + + int8_t setFrameRate(GridEye::FrameRate rate); + +}; + + +void convRaw8x8Data2Int(char * data, int16_t * frame_temp); + +void convRaw8x8Data2Point25degC(char * data, int16_t * frame_temp); + +void convSingleRawTempData2Int(char * data, int16_t & pixel_temp); + +#endif /*GridEye_H*/ \ No newline at end of file
--- a/SX1276GenericPingPong/GenericPingPong.cpp Fri Jul 13 18:22:53 2018 +0000 +++ b/SX1276GenericPingPong/GenericPingPong.cpp Wed Jul 18 18:52:30 2018 +0000 @@ -221,7 +221,7 @@ uint8_t i; #if defined(TARGET_MAX32630FTHR) // Master Device: Bluetooth Gateway bool isMaster = true; -#elif defined(TARGET_MAX32620FTHR) // Client Device: Robot +#elif defined(TARGET_MAX32620FTHR) // Slave Device: Robot bool isMaster = false; #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/global_buffers.h Wed Jul 18 18:52:30 2018 +0000 @@ -0,0 +1,36 @@ +/** Description: + * This File is responsible for defining the buffers that will be used in + * various areas of the program. The buffers that are defined here will be + * refferenced in the main.cpp and will be filled with data in one of two ways: + * + * 1. The buffers will be filled with data upon receiving a successful payload + * transmission over LoRa. In GenericPingPong.cpp, the function OnRxDone() + * will call the function fillGlobalBufsWithPayload() that is responsible for + * filling the appropriate buffers with the payload data that was received + * by either the master or slave device by the other device that sent it. + * + * 2. The buffers will be used to fill up a payload buffer that will be sent + * over LoRa by either the master or slave device to the receiving device. + * The function fillPayloadWithGlobalBufs() will use the global buffers that + * are filled with data for various sensors in the main.cpp to construct a + * payload to deliver to the other device when SX1276PingPong() is called + * in file GenericPingPong.cpp. + * + */ + +#ifndef __GLOBAL_BUFFERS_H__ +#define __GLOBAL_BUFFERS_H__ + +/*************************************************************************** + * Grid Eye Sensor Information + **************************************************************************/ +#if defined(TARGET_MAX32630FTHR) // Master Device: BLE-to-LoRa Gateway + char curr_raw_frame_data_from_slave[128]; + char prev_raw_frame_data_from_slave[128]; + int16_t conv_frame_data_from_slave[64]; +#elif defined(TARGET_MAX32620FTHR) // Client Device: LoRa Controlled Robot + char curr_raw_frame_data_to_master[128]; +#endif + + +#endif // __GLOBAL_BUFFERS_H__ \ No newline at end of file
--- a/main.cpp Fri Jul 13 18:22:53 2018 +0000 +++ b/main.cpp Wed Jul 18 18:52:30 2018 +0000 @@ -10,7 +10,17 @@ */ #include "main.h" + #include "global_buffers.h" + #include "GridEye.h" + +/* 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. + */ #if defined(TARGET_MAX32630FTHR) // using the RFM95 board #include "max32630fthr.h" MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); @@ -19,13 +29,23 @@ DigitalOut myled(LED); -int main() { -#ifdef HELTEC_STM32L4 - DigitalOut vext(POWER_VEXT); - vext = POWER_VEXT_ON; -#endif +#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 functin 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: Robot + //Init I2C communications in default I2C bus I2C #1 + I2C i2cGridEye(P3_4,P3_5); + GridEye gridEye(i2cGridEye); +#endif - +int main() +{ /* * inits the Serial or USBSerial when available (230400 baud). * If the serial uart is not is not connected it swiches to USB Serial @@ -36,10 +56,71 @@ dprintf("Welcome to the SX1276GenericLib"); dprintf("Starting a simple LoRa PingPong"); + + /* Setup begins here: */ + + /*************************************************************************** + * Lora Communications + **************************************************************************/ SX1276PingPongSetup(); + + /*************************************************************************** + * 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) // Client Device: LoRa Controlled Robot + // none yet + #endif + + while(1) - { + { + /*************************************************************************** + * 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( memcmp(prev_raw_frame_data_from_slave, curr_raw_frame_data_from_slave, sizeof(curr_raw_frame_data_from_slave)) != 0 ) + { + // Convert raw data sent from slave to a 16 bit integer array by calling this + convRaw8x8Data2Point25degC(curr_raw_frame_data_from_slave, conv_frame_data_from_slave); + + // Next Print off the Converted data + dprintf("\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 = conv_frame_data_from_slave[idx]/4.0; + dprintf("%.2f \t", pixel_data); + } + dprintf("\r\n\r\n"); + } + dprintf("\r\n"); + + // Increment frame counter + frame_idx = frame_idx +1; + } + + #elif defined(TARGET_MAX32620FTHR) // Client Device: LoRa Controlled Robot + // Aquire raw data about 8x8 frame from the grid eye sensor in this function call + gridEye.getRaw8x8FrameData(curr_raw_frame_data_to_master); + + #endif + + + /*************************************************************************** + * Lora Communications + **************************************************************************/ SX1276PingPong(); + + + + + } }