From 5e3be0f5615d55d76ec1a09cd919add82cb21bdf Mon Sep 17 00:00:00 2001 From: "A.M. Rowsell" Date: Mon, 21 Jan 2019 19:53:42 -0500 Subject: [PATCH] It's alive! New code all working. The OneWire library works. It's a bit hacked together, as neither the software timer or hardware timer APIs would have worked well, because they are implemented terribly by Espressif. The easiest way to get around this was to just use system_get_time() and work off of that for timing in one-wire comms. Split the publish function into two separate functions: one to publish floating point numbers, and one to publish integers. In a language like Lua or C++ you could have these as one function, but in C it's easier to just split them. The main.c has a new function called dataLog that deals with getting the DS18B20 data and then handing that off to pubfloat(). I updated the timer names to be more descriptive. I grabbed some code to convert integers and floats to strings, as I can't be bothered to write that code myself for the millionth time. If something goes wrong and we are disconnected from our TCP connection, all timers are halted so we don't blindly keep trying to send packets over a non-existent link. Unfortunately the onewire library is hardcoded to use pin 5. That will be the next update. Signed-off-by: A.M. Rowsell --- Makefile | 4 +- main.c | 99 ++++++++++++++++++++++++++++++++------------ main.h | 11 ++++- mqtt.c | 68 +++++++++++++++++++++++++++++++ mqtt.h | 1 + onewire.c | 120 ++++++++++++++++++++++++++++++++++-------------------- onewire.h | 3 +- 7 files changed, 231 insertions(+), 75 deletions(-) diff --git a/Makefile b/Makefile index 301df07..4d82140 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,10 @@ $(P): $(OBJ) %.o: %.c $(DEPS) flash: $(P)-0x00000.bin - esptool.py --port /dev/feather1 write_flash 0 $(P)-0x00000.bin 0x10000 $(P)-0x10000.bin + esptool.py --port /dev/feather0 write_flash 0 $(P)-0x00000.bin 0x10000 $(P)-0x10000.bin clean: - rm -f $(P) $(OBJ) $(P)-0x00000.bin $(P)-0x10000.bin + rm -f $(P) $(OBJ) $(P)-0x00000.bin $(P)-0x10000.bin *~ library: $(CC) -c -fPIC $(CFLAGS) $(P).c -o $(P).o diff --git a/main.c b/main.c index 79ef9c6..5fa0189 100644 --- a/main.c +++ b/main.c @@ -9,37 +9,54 @@ #include "onewire.h" #include "main.h" -static os_timer_t oneTimer; -static os_timer_t testTimer; +os_timer_t tcpTimer; +os_timer_t pingTimer; +os_timer_t pubTimer; LOCAL void ICACHE_FLASH_ATTR con(void *arg) { os_printf("Entered con!\n"); mqtt_session_t *pSession = (mqtt_session_t *)arg; mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_CONNECT); - os_timer_disarm(&oneTimer); - os_timer_setfn(&oneTimer, (os_timer_func_t *)sub, arg); - os_timer_arm(&oneTimer, 200, 0); + os_timer_disarm(&pingTimer); + os_timer_setfn(&pingTimer, (os_timer_func_t *)ping, arg); + os_timer_arm(&pingTimer, 1000, 0); } -LOCAL void ICACHE_FLASH_ATTR pub(void *arg) { - os_printf("Entered pub!\n"); +LOCAL void ICACHE_FLASH_ATTR pubuint(void *arg) { + os_printf("Entered pubuint!\n"); mqtt_session_t *pSession = (mqtt_session_t *)arg; - uint8_t data[] = "2.718281828459045"; - int32_t dataLen = os_strlen(data); - mqtt_send(pSession, &data[0], dataLen, MQTT_MSG_TYPE_PUBLISH); - os_timer_disarm(&oneTimer); - os_timer_setfn(&oneTimer, (os_timer_func_t *)ping, arg); - os_timer_arm(&oneTimer, 200, 0); + uint8_t *data = (uint8_t *)(pSession->userData); + char *dataStr = os_zalloc(20 * sizeof(char)); + intToStr(*data, dataStr, 4); + int32_t dataLen = os_strlen(dataStr); + mqtt_send(pSession, (uint8_t *)dataStr, dataLen, MQTT_MSG_TYPE_PUBLISH); + os_timer_disarm(&pingTimer); + os_timer_setfn(&pingTimer, (os_timer_func_t *)ping, arg); + os_timer_arm(&pingTimer, 1000, 0); +} + +LOCAL void ICACHE_FLASH_ATTR pubfloat(void *arg) { + os_printf("Entered pubfloat!\n"); + mqtt_session_t *pSession = (mqtt_session_t *)arg; + float *data = (float *)(pSession->userData); + char *dataStr = os_zalloc(20 * sizeof(char)); + ftoa(*data, dataStr, 2); + int32_t dataLen = os_strlen(dataStr); + os_printf("Encoded string: %s\tString length: %d\n", dataStr, dataLen); + mqtt_send(pSession, (uint8_t *)dataStr, dataLen, MQTT_MSG_TYPE_PUBLISH); + os_timer_disarm(&pingTimer); + os_timer_setfn(&pingTimer, (os_timer_func_t *)ping, arg); + os_timer_arm(&pingTimer, 1000, 0); } LOCAL void ICACHE_FLASH_ATTR ping(void *arg) { os_printf("Entered ping!\n"); mqtt_session_t *pSession = (mqtt_session_t *)arg; mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_PINGREQ); - os_timer_disarm(&oneTimer); - os_timer_setfn(&oneTimer, (os_timer_func_t *)sub, arg); - os_timer_arm(&oneTimer, 200, 0); + os_timer_disarm(&pingTimer); + os_timer_setfn(&pingTimer, (os_timer_func_t *)ping, arg); + os_timer_arm(&pingTimer, 1000, 0); } LOCAL void ICACHE_FLASH_ATTR sub(void *arg) { @@ -53,33 +70,59 @@ LOCAL void ICACHE_FLASH_ATTR discon(void *arg) { os_printf("Entered discon!\n"); mqtt_session_t *pSession = (mqtt_session_t *)arg; mqtt_send(pSession, NULL, 0, MQTT_MSG_TYPE_DISCONNECT); - os_timer_disarm(&oneTimer); + os_timer_disarm(&pingTimer); +} + +LOCAL void ICACHE_FLASH_ATTR dataLog(void *arg) { + mqtt_session_t *pSession = (mqtt_session_t *)arg; + oneWire_t DS18; + oneWire_t *pDS18 = &DS18; + uint16_t temp = 0; + sint32 time = 0; + pDS18->temperature = 0; + reset(); + transact(pDS18, SKIP_ROM); + transact(pDS18, CONVERT_T); + time = system_get_time() + 750000; + while(system_get_time() < time); + reset(); + transact(pDS18, SKIP_ROM); + transact(pDS18, SCRATCH_READ); + //os_printf("\nReceived onewire data: %x %x\n", pDS18->scratchpad[0], pDS18->scratchpad[1]); + temp = ((uint16_t)pDS18->scratchpad[1] << 8) | pDS18->scratchpad[0]; + pDS18->temperature += (temp >> 4) + ((temp & 0x0F) * 0.0625); + pSession->userData = (void *)&pDS18->temperature; + os_printf("\nTemperature is: %d.%02d\n", (int)pDS18->temperature, (int)(pDS18->temperature * 100) % 100); + pubfloat(pSession); // publish the temperature + } void ICACHE_FLASH_ATTR user_init() { //uint8_t wifiStatus; LOCAL mqtt_session_t globalSession; LOCAL mqtt_session_t *pGlobalSession = &globalSession; - char ssid[32] = "yourwifissid"; - char passkey[64] = "yourwifipassword"; + char ssid[32] = "Kwangmyong"; + char passkey[64] = "vqmfg55020"; struct station_config stationConf; gpio_init(); // init gpio so we can use the LED + uart_div_modify(0, UART_CLK_FREQ / 115200); // set UART to 115200 wifi_status_led_install(0, PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); // set GPIO0 as status LED stationConf.bssid_set = 0; os_memcpy(&stationConf.ssid, ssid, 32); // copy the ssid and passkey into the station_config struct os_memcpy(&stationConf.password, passkey, 64); wifi_set_opmode_current(0x01); //station mode wifi_station_set_config_current(&stationConf); // tell it about our config, this auto-connects us as well - // prepare the TCP/MQTT connection stuff // Adafruit IO is at 52.5.238.97 static const char ioUser[11] = { 0x4d, 0x72, 0x41, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x75, 0x73, 0x52 }; // MrAureliusR static const uint8_t ioUser_len = 11; static const char ioKey[32] = { 0x32, 0x63, 0x39, 0x36, 0x65, 0x30, 0x35, 0x61, 0x66, 0x34, 0x35, 0x30, 0x34, 0x31, 0x66, 0x31, 0x38, 0x36, 0x65, 0x62, 0x39, 0x30, 0x33, 0x32, 0x33, 0x31, 0x31, 0x31, 0x61, 0x32, 0x61, 0x38 }; // 2c96e05af45041f186eb90323111a2a8 static const uint8_t ioKey_len = 32; - static const char ioTopic[37] = { 0x4d, 0x72, 0x41, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x75, 0x73, 0x52, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2f, 0x62, 0x65, 0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x62, 0x65, 0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x74, 0x65, 0x6d, 0x70 }; - static const uint8_t ioTopic_len = 37; - static const char clientID[5] = { 0x46, 0x5a, 0x5a, 0x4e, 0x30 }; + static const char ioTopic[27] = { 0x4d, 0x72, 0x41, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x75, 0x73, 0x52, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x74, 0x6f, 0x70, 0x69, 0x63 }; // MrAureliusR/feeds/testtopic + static const uint8_t ioTopic_len = 27; + /* static const char ioTopic[37] = { 0x4d, 0x72, 0x41, 0x75, 0x72, 0x65, 0x6c, 0x69, 0x75, 0x73, 0x52, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2f, 0x62, 0x65, 0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x62, 0x65, 0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x74, 0x65, 0x6d, 0x70 }; */ + /* static const uint8_t ioTopic_len = 37; */ + static const char clientID[5] = { 0x46, 0x52, 0x5a, 0x4e, 0x30 }; // FRZN0 static const uint8_t clientID_len = 5; pGlobalSession->port = 1883; // mqtt port static const char adafruitIO_ip[4] = {52, 5, 238, 97}; @@ -97,8 +140,10 @@ void ICACHE_FLASH_ATTR user_init() { pGlobalSession->client_id = os_zalloc(sizeof(uint8_t) * pGlobalSession->client_id_len); os_memcpy(pGlobalSession->client_id, clientID, pGlobalSession->client_id_len); - os_timer_setfn(&oneTimer, (os_timer_func_t *)tcpConnect, pGlobalSession); - os_timer_arm(&oneTimer, 15000, 0); - os_timer_setfn(&testTimer, (os_timer_func_t *)con, pGlobalSession); - os_timer_arm(&testTimer, 16000, 0); + os_timer_setfn(&tcpTimer, (os_timer_func_t *)tcpConnect, pGlobalSession); + os_timer_arm(&tcpTimer, 12000, 0); + os_timer_setfn(&pingTimer, (os_timer_func_t *)con, pGlobalSession); + os_timer_arm(&pingTimer, 16000, 0); + os_timer_setfn(&pubTimer, (os_timer_func_t *)dataLog, pGlobalSession); + os_timer_arm(&pubTimer, 20000, 1); } diff --git a/main.h b/main.h index 846495c..b37edbe 100644 --- a/main.h +++ b/main.h @@ -1,7 +1,16 @@ #include "os_type.h" +extern os_timer_t tcpTimer; +extern os_timer_t pingTimer; +extern os_timer_t pubTimer; + +void reverse(char *str, int len); +int intToStr(int x, char str[], int d); +void ftoa(float n, char *res, int afterpoint); + LOCAL void ICACHE_FLASH_ATTR con(void *arg); -LOCAL void ICACHE_FLASH_ATTR pub(void *arg); +LOCAL void ICACHE_FLASH_ATTR pubuint(void *arg); +LOCAL void ICACHE_FLASH_ATTR pubfloat(void *arg); LOCAL void ICACHE_FLASH_ATTR sub(void *arg); LOCAL void ICACHE_FLASH_ATTR ping(void *arg); LOCAL void ICACHE_FLASH_ATTR discon(void *arg); diff --git a/mqtt.c b/mqtt.c index 5b2f0fd..7192c25 100644 --- a/mqtt.c +++ b/mqtt.c @@ -3,6 +3,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include +#include #include "user_interface.h" #include "ets_sys.h" #include "osapi.h" @@ -12,6 +13,7 @@ #include "os_type.h" #include "mqtt.h" #include "onewire.h" +#include "main.h" /* Functions we will need to implement: * Send -- will handle all sending of all packets @@ -25,6 +27,67 @@ static os_timer_t MQTT_KeepAliveTimer; static os_timer_t waitForWifiTimer; +// reverses a string 'str' of length 'len' +void reverse(char *str, int len) +{ + int i=0, j=len-1, temp; + while (i> 4) & 0x1; - if(presence) { + uint8_t presence = (uint8_t)(gpio_input_get() >> 5) & 0x1; + // give a 480uS pause so the next onewire event doesn't get trampled + time = system_get_time() + 480; + while(system_get_time() < time); + + if(!presence) { return 1; } else { return -1; @@ -27,47 +33,73 @@ void ICACHE_FLASH_ATTR transact(oneWire_t *owDev, ds18b20_cmds cmd) { uint8_t sendBit; uint8_t inBit = 0x00; uint8_t inByte = 0x00; - if((cmd == SKIP_ROM) | (cmd == CONVERT_T)) { - for(uint8_t i = 7; i >= 0; i--) { - sendBit = (cmd >> i) & 0x1; - if(sendBit == 1) { - time = system_get_time() + 10; - gpio_output_set(0, BIT4, BIT4, 0); // pull low - while(system_get_time() < time); - gpio_output_set(0, 0, 0, BIT4); // let go - } else { - time = system_get_time() + 100; - gpio_output_set(0, BIT4, BIT4, 0); //pull low - while(system_get_time() < time); - gpio_output_set(0, 0, 0, BIT4); + switch(cmd) { + os_printf("\nOnewire command: %d\n", cmd); + case SKIP_ROM: + case CONVERT_T: + for(uint8_t i = 0; i < 8; i++) { + sendBit = (cmd >> i) & 0x1; + //os_printf("\nThe bit is: %d \t i is %d\n", sendBit, i); + if(sendBit == 1) { + //os_printf("\nWe are in sendBit == 1\n"); + time = system_get_time() + 10; + gpio_output_set(0, OWBUS, OWBUS, 0); // pull low + while(system_get_time() < time); + gpio_output_set(0, 0, 0, OWBUS); // let go + time = system_get_time() + 50; + while(system_get_time() < time); + } else { + //os_printf("\nWe are in the sendBit else\n"); + time = system_get_time() + 100; + gpio_output_set(0, OWBUS, OWBUS, 0); //pull low + while(system_get_time() < time); + gpio_output_set(0, 0, 0, OWBUS); // let go + time = system_get_time() + 10; + while(system_get_time() < time); + } } - } - } else if(cmd == SCRATCH_READ) { - for(uint8_t i = 7; i >= 0; i--) { - sendBit = (cmd >> i) & 0x1; - if(sendBit == 1) { - time = system_get_time() + 10; - gpio_output_set(0, BIT4, BIT4, 0); // pull low - while(system_get_time() < time); - gpio_output_set(0, 0, 0, BIT4); // let go - } else { - time = system_get_time() + 100; - gpio_output_set(0, BIT4, BIT4, 0); //pull low - while(system_get_time() < time); - gpio_output_set(0, 0, 0, BIT4); + break; + case SCRATCH_READ: + for(uint8_t i = 0; i < 8; i++) { + sendBit = (cmd >> i) & 0x1; + if(sendBit == 1) { + //os_printf("\nWe are in sendBit == 1\n"); + time = system_get_time() + 10; + gpio_output_set(0, OWBUS, OWBUS, 0); // pull low + while(system_get_time() < time); + gpio_output_set(0, 0, 0, OWBUS); // let go + time = system_get_time() + 50; + while(system_get_time() < time); + } else { + //os_printf("\nWe are in the sendBit else\n"); + time = system_get_time() + 100; + gpio_output_set(0, OWBUS, OWBUS, 0); //pull low + while(system_get_time() < time); + gpio_output_set(0, 0, 0, OWBUS); // let go + time = system_get_time() + 10; + while(system_get_time() < time); + } } - } - // now read the scratchpad - for(uint8_t i = 0; i < 2; i++) { - for(uint8_t j = 0; j < 8; j++) { - time = system_get_time() + 8; - gpio_output_set(0, BIT4, BIT4, 0); - while(system_get_time() < time); - gpio_output_set(0, 0, 0, BIT4); - inBit = (uint8_t)(gpio_input_get() >> 4) & 0x01; - inByte |= inBit << j; + // now read the scratchpad + for(uint8_t i = 0; i < 2; i++) { + for(uint8_t j = 0; j < 8; j++) { + time = system_get_time() + 8; + gpio_output_set(0, OWBUS, OWBUS, 0); + while(system_get_time() < time); + gpio_output_set(0, 0, 0, OWBUS); + time = system_get_time() + 15; + while(system_get_time() < time); + inBit = (uint8_t)(gpio_input_get() >> 5) & 0x01; + inByte |= inBit << j; + time = system_get_time() + 45; + while(system_get_time() < time); + } + owDev->scratchpad[i] = inByte; + inByte = 0; // clear inByte } - owDev->scratchpad[i] = inByte; - } + break; + default: + os_printf("\nIncorrect command\n"); + break; } } diff --git a/onewire.h b/onewire.h index 6c36d46..9993365 100644 --- a/onewire.h +++ b/onewire.h @@ -9,6 +9,7 @@ typedef struct { uint8_t address[8]; uint8_t scratchpad[9]; + float temperature; } oneWire_t; /** @@ -28,5 +29,5 @@ typedef enum { E2_RECALL = 0xB8 } ds18b20_cmds; -sint8 ICACHE_FLASH_ATTR init(oneWire_t *owDev); +sint8 ICACHE_FLASH_ATTR reset(void); void ICACHE_FLASH_ATTR transact(oneWire_t *owDev, ds18b20_cmds cmd);