#include #include #include "main.h" #include "CatOneTask.h" #include "LoraTask.h" #include "CatOneTask.h" #include "RS485Task.h" #include "DebugCmd.h" #include "spiflash.h" //雅下: 81-00-00-06-00-01 // 81-00-00-06-00-02 // 81-00-00-06-00-03 // 81-00-00-06-00-04 // 81-00-00-06-00-05 // 81-00-00-06-00-06 // 81-00-00-06-00-07 // 81-00-00-06-00-08 // 81-00-00-06-00-09 // 81-00-00-06-00-0A static const uint8_t GateWayMac_Test[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x00}; static const uint8_t GateWayMac_BL1[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x01}; static const uint8_t GateWayMac_BL2[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x02}; static const uint8_t GateWayMac_BL3[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x03}; static const uint8_t GateWayMac_BL4[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x04}; static const uint8_t GateWayMac_BL5[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x05}; static const uint8_t GateWayMac_BL6[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x06}; static const uint8_t GateWayMac_BL7[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x07}; static const uint8_t GateWayMac_BL8[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x08}; static const uint8_t GateWayMac_BL9[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x09}; static const uint8_t GateWayMac_BL10[6] = {0x81, 0x00, 0x00, 0x06, 0x00, 0x0A}; bool MainDispEn = true; static rt_thread_t Lora_Thread = RT_NULL; static rt_thread_t Cat1Eth_Thread = RT_NULL; static rt_thread_t RS485Ch1_Thread = RT_NULL; static rt_thread_t RS485Ch2_Thread = RT_NULL; static rt_thread_t Debug_Thread = RT_NULL; GateWayPara_t GateWay; #define ARRAY_DIM(a) (sizeof(a) / sizeof((a)[0])) //static int Battery_Level_Percent_Table[11] = {3000, 3650, 3700, 3740, 3760, 3795, 3840, 3910, 3980, 4070, 4150}; static int Battery_Level_Percent_Table[11] = {6000, 7300, 7400, 7480, 7520, 7590, 7680, 7820, 7960, 8140, 8300}; int toPercentage(int voltage) { int i; if(voltage < Battery_Level_Percent_Table[0]) return 0; for(i = 0; i 0 // GateWay.ConfigPara.SvrAddr[0] = 39; // GateWay.ConfigPara.SvrAddr[1] = 106; // GateWay.ConfigPara.SvrAddr[2] = 103; // GateWay.ConfigPara.SvrAddr[3] = 147; // GateWay.ConfigPara.SvrPort = 8080; GateWay.ConfigPara.SvrAddr[0] = 103; GateWay.ConfigPara.SvrAddr[1] = 217; GateWay.ConfigPara.SvrAddr[2] = 192; GateWay.ConfigPara.SvrAddr[3] = 248; GateWay.ConfigPara.SvrPort = 12111; #endif if(GateWay.ConfigPara.DebugChannel == DEBUG_CH_RS485_1) { GateWay.ConfigPara.Rs485Ch1.Enable = true; GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000; } if(GateWay.ConfigPara.Rs485Ch1.BaudRate < 2400 || GateWay.ConfigPara.Rs485Ch1.BaudRate > 921600) GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000; RS485Ch1_Config(GateWay.ConfigPara.Rs485Ch1.BaudRate); if(GateWay.ConfigPara.DebugChannel == DEBUG_CH_RS485_2) { GateWay.ConfigPara.Rs485Ch2.Enable = true; GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000; } if(GateWay.ConfigPara.Rs485Ch2.BaudRate < 2400 || GateWay.ConfigPara.Rs485Ch2.BaudRate > 921600) GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000; RS485Ch2_Config(GateWay.ConfigPara.Rs485Ch2.BaudRate); if(GateWay.ConfigPara.Rs485Ch1.Power) RS485_CH1_POW_ON(); else RS485_CH1_POW_OFF(); if(GateWay.ConfigPara.Rs485Ch2.Power) { RS485_CH2_POW_OFF(); rt_thread_delay(1000); RS485_CH2_POW_ON(); } else RS485_CH2_POW_OFF(); if(GateWay.ConfigPara.Lora.OnOff == true) { LORA_POW_ON(); } else { LORA_POW_OFF(); } if(LoraSetChannel(GateWay.ConfigPara.Lora.ucChannel) == false) { GateWay.ConfigPara.Lora.ucChannel = 8; LoraSetChannel(GateWay.ConfigPara.Lora.ucChannel); //WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); } if(LoraSetPower(GateWay.ConfigPara.Lora.ucPower) == false) { GateWay.ConfigPara.Lora.ucPower = 20; LoraSetPower(GateWay.ConfigPara.Lora.ucPower); //WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); } if(LoraSetSignalBw(GateWay.ConfigPara.Lora.SignalBw) == false) { GateWay.ConfigPara.Lora.SignalBw = 8; LoraSetSignalBw(GateWay.ConfigPara.Lora.SignalBw); //WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); } if(LoraSetSpreadFactor(GateWay.ConfigPara.Lora.SpreadFactor) == false) { GateWay.ConfigPara.Lora.SpreadFactor = 9; LoraSetSpreadFactor(GateWay.ConfigPara.Lora.SpreadFactor); //WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); } if(LoraSetErrorCoding(GateWay.ConfigPara.Lora.ErrorCoding) == false) { GateWay.ConfigPara.Lora.ErrorCoding = 2; LoraSetErrorCoding(GateWay.ConfigPara.Lora.ErrorCoding); //WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); } if(GateWay.ConfigPara.Lora.RegPreamble > 0xFE) { GateWay.ConfigPara.Lora.RegPreamble = 10; //WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); } LoraSetRegPreamble(GateWay.ConfigPara.Lora.RegPreamble); WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); LogInit(); Header.LogEndAddr = 0; if(ReadLogNum() > 0) { int ret = ReadLog(&Header, NULL, 0); if(ret > 0) { GateWay.HistoryNum = ReadLogNum() - Header.LogIdx + 1; rt_kprintf("History Num: %d\r\n", GateWay.HistoryNum); } else { rt_kprintf("History Num: 0\r\n"); } } else rt_kprintf("History Num: 0\r\n"); if(GateWay.ConfigPara.Comm == CATONE_COMM) { CAT1_ON(); } else { ETH_ON(); } } void OutageUpdate(uint8_t AlarmType, bool AlarmState, uint8_t Batt) { GateWayAlarmType_t *Alarm; uint8_t MegData[6],len; len = sizeof(GateWayAlarmType_t); MegData[0] = len & 0x00ff;; MegData[1] = (len >> 8) & 0x00ff; MegData[2] = NET_COMM_CMD_ALARM; Alarm = (GateWayAlarmType_t *)&MegData[3]; Alarm->AlarmType = AlarmType; Alarm->AlarmState = AlarmState; Alarm->AlarmPara = Batt; CatOneEthSendQueue(MegData, 6); //发送报警信息 } /***************************************************************************************** * 函数名称: main * 功能描述: 主函数 * 参 数: 无 * 返 回 值: 运行错误返回-1 *****************************************************************************************/ static uint8_t LastBattery = 0xff; //上一次电池电压 int main(void) { uint16_t OneSecondDlyCnt = 0; // struct tm cTime; uint16_t PowerONLedDly = 2000; uint32_t SystemRseetDlyCnt = 0; uint32_t BatteryUpdateDlyCnt = 0; uint8_t AlarmType = 0; GateWayInit(); rt_kprintf("\r\n\r\n"); rt_kprintf("****************************************************\r\n"); rt_kprintf("** **\r\n"); rt_kprintf("** GateWay **\r\n"); rt_kprintf("** SoftWare V%d.%d **\r\n", SOFTWARE_VERSION / 10, SOFTWARE_VERSION % 10); rt_kprintf("** HardWare V%d.%d **\r\n", HARDWARE_VERSION / 10, HARDWARE_VERSION % 10); rt_kprintf("** Compile: %s %s **\r\n", __DATE__, __TIME__); rt_kprintf("** **\r\n"); rt_kprintf("****************************************************\r\n\r\n"); // TimeGet(&cTime); // TimeShow(TimeTs()); FeedDog(); //rt_thread_delay(500); //InfTest(); //FeedDog(); //Cat1DBGOnOff(true); GateWay.CommUnitRevCallBack = CommUnitAnalyze; GateWay.SvrRevCallBack = Cat1EthRevCallBack; GateWay.NetSendData_MQ = rt_mq_create("NetSendMQ", 512, 10, RT_IPC_FLAG_FIFO); if(GateWay.NetSendData_MQ == RT_NULL) { rt_kprintf("CatOne MQ Create Failed!\r\n"); } GateWay.LoraRev_MQ = rt_mq_create("LoraRevMQ", 256, 10, RT_IPC_FLAG_FIFO); if(GateWay.LoraRev_MQ == RT_NULL) { rt_kprintf("LoraRev MQ Create Failed!\r\n"); } GateWay.UartRevMutex = rt_mutex_create("urmutex", RT_IPC_FLAG_FIFO); if(GateWay.UartRevMutex == RT_NULL) { rt_kprintf("UR Mutex Create Failed!\r\n"); } GateWay.SvrRevCallBack = Cat1EthRevCallBack; RS485Ch1_Thread = rt_thread_create("RS485Ch1", RS485Ch1_Thread_Entry, &GateWay, 2048, 3, 20); if (RS485Ch1_Thread != RT_NULL) rt_thread_startup(RS485Ch1_Thread); else return -1; RS485Ch2_Thread = rt_thread_create("RS485Ch2", RS485Ch2_Thread_Entry, &GateWay, 2048, 3, 20); if (RS485Ch2_Thread != RT_NULL) rt_thread_startup(RS485Ch2_Thread); else return -1; Debug_Thread = rt_thread_create("DebugUart", Debug_Thread_Entry, &GateWay, 2048, 3, 20); if (RS485Ch2_Thread != RT_NULL) rt_thread_startup(Debug_Thread); else return -1; Cat1Eth_Thread = rt_thread_create("Cat1Eth", CatOne_Eth_Thread_Entry, &GateWay, 4096, 3, 20); if (Cat1Eth_Thread != RT_NULL) rt_thread_startup(Cat1Eth_Thread); else return -1; Lora_Thread = rt_thread_create("Lora", Lora_Thread_Entry, &GateWay, 1024, 3, 20); if (Lora_Thread != RT_NULL) rt_thread_startup(Lora_Thread); else return -1; while(1) { if(PowerONLedDly > 0) { PowerONLedDly--; if(PowerONLedDly == 1) { POWER_LED_OFF(); } } EthRxOverhandler(); RS485RxOverhandler(); DebugRxOverhandler(); if(OneSecondDlyCnt % 200 == 0) { FeedDog(); LORA_RX_TOGGLE(); POWER_TOGGLE(); } OneSecondDlyCnt++; if(OneSecondDlyCnt == 1000) { OneSecondDlyCnt = 0; if(GateWay.BatteryReadDlyCnt > 0) { GateWay.BatteryReadDlyCnt--; continue; } uint16_t ADValue = GetADCBuffPoint(); //V = (AD * 3.3 / 4096) * (R1+R2) / R1; R1 = 200, R2 = 120 //计算出常数为0.0021484375,扩大1000倍 float Voltage = ADValue * 2.1484375; GateWay.Battery = toPercentage(Voltage); //上电判断电量 if(LastBattery == 0xff) { LastBattery = GateWay.Battery; if(GateWay.ConfigPara.OutageFlag == true) { //有报警 AlarmType = 1; } else { AlarmType = 0; } //BatteryUpdateDlyCnt = 2 * 60; BatteryUpdateDlyCnt = 10; } else { if(GateWay.ConfigPara.OutageFlag == false) { //没有告警,判断电池电压是否降低 if(GateWay.Battery <= LastBattery) { if(LastBattery <= 5) { GateWay.ConfigPara.OutageFlag = true; WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); Debug_Printf("The power is cutted.(1) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery); LastBattery = GateWay.Battery; AlarmType = 1; OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery); BatteryUpdateDlyCnt = 20 * 60; } else if((LastBattery - GateWay.Battery) > 2) { GateWay.ConfigPara.OutageFlag = true; WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); LastBattery = GateWay.Battery; AlarmType = 1; Debug_Printf("The power is cutted.(2) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery); OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery); BatteryUpdateDlyCnt = 20 * 60; } } else { //充电,更新上一次电池电压 LastBattery = GateWay.Battery; } } else { if(GateWay.Battery >= LastBattery) { if(LastBattery > 95) { GateWay.ConfigPara.OutageFlag = false; WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); Debug_Printf("The power is restored.(1) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery); LastBattery = GateWay.Battery; AlarmType = 1; OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery); BatteryUpdateDlyCnt = 90 * 60; AlarmType = 0; } else if(GateWay.Battery - LastBattery > 5) { GateWay.ConfigPara.OutageFlag = false; WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t)); Debug_Printf("The power is restored.(2) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery); LastBattery = GateWay.Battery; AlarmType = 1; OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery); BatteryUpdateDlyCnt = 90 * 60; AlarmType = 0; } } else { //电池继续放电,更新上一次电池电压 LastBattery = GateWay.Battery; } } } BatteryUpdateDlyCnt--; if(BatteryUpdateDlyCnt == 0) { if(GateWay.ConfigPara.OutageFlag) { //有报警 BatteryUpdateDlyCnt = 20 * 60; } else { BatteryUpdateDlyCnt = 90 * 60; } OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery); } //ADC_Start(); } SystemRseetDlyCnt++; if(SystemRseetDlyCnt > (24 * 60 * 60 * 1000)) { SystemRseetDlyCnt = 0; Debug_Printf("The system resets periodically.\r\n"); rt_thread_delay(10); NVIC_SystemReset(); } rt_thread_delay(1); } } #if 0 static FATFS SDFatFs; static FIL TestFile; static uint8_t u8WorkBuffer[FF_MAX_SS]; void FSInit(void) { FRESULT fRet; uint32_t u32WBNbr, u32RBNbr; char SDPath[] = "1:"; MKFS_PARM opt; uint8_t u8ReadText[100]; en_result_t enTestRet = Error; uint8_t u8WriteText[] = "This is a string used to test the FatFs"; if (FR_OK != f_mount(&SDFatFs, (TCHAR const*)SDPath, 0U)) { rt_kprintf("FatFs Initialization Error!\r\n"); } else { memset(&opt, 0, sizeof(MKFS_PARM)); opt.fmt = (BYTE)FM_FAT32; /* Create a FAT file system (format) on the logical drive */ if (FR_OK != f_mkfs((TCHAR const*)SDPath, &opt, u8WorkBuffer, sizeof(u8WorkBuffer))) { rt_kprintf("FatFs Format Error!\r\n"); } else { /* Create and Open a new text file object with write access */ if (FR_OK != f_open(&TestFile, "1:Test.txt", ((BYTE)FA_CREATE_ALWAYS | (BYTE)FA_WRITE))) { rt_kprintf("\"Test.txt\" file Open for write Error!\r\n"); } else { /* Write data to the text file */ fRet = f_write(&TestFile, u8WriteText, sizeof(u8WriteText), (void *)&u32WBNbr); if ((0UL == u32WBNbr) || (FR_OK != fRet)) { rt_kprintf("\"Test.txt\" file Write or EOF Error!\r\n"); else { /* Close the open text file */ f_close(&TestFile); /* Open the text file object with read access */ if (FR_OK != f_open(&TestFile, "1:Test.txt", (BYTE)FA_READ)) { rt_kprintf("\"Test.txt\" file Open for read Error!\r\n"); } else { memset(u8ReadText, 0, sizeof(u8ReadText)); /* Read data from the text file */ fRet = f_read(&TestFile, u8ReadText, sizeof(u8ReadText), (UINT*)(uint32_t)&u32RBNbr); if ((0UL == u32RBNbr) || (FR_OK != fRet)) { rt_kprintf("\"Test.txt\" file Read or EOF Error!\r\n"); } else { /* Close the open text file */ f_close(&TestFile); /* Compare read data with the expected data */ if (u32RBNbr == u32WBNbr) { /* Check data value */ if (0 == memcmp(u8WriteText, u8ReadText, u32RBNbr)) { enTestRet = Ok; } } } } } } } } /* Unlink the micro SD disk I/O driver */ f_mount(NULL, (TCHAR const*)SDPath, 0U); if(enTestRet != Ok) { rt_kprintf("Error!\r\n"); } else { rt_kprintf("Ok!\r\n"); } } #endif