-
Some Software - Very early test code
03/10/2015 at 13:25 • 0 commentsHere is some sample code that seems to work OK. Need to test with a real pulse generator.
big thanks to http://www.limpkin.fr/index.php?post/2014/12/07/First-Steps-with-the-ESP8266-03-Development-Board
on which this code is based.
#include "c_types.h" #include "ip_addr.h" #include "ets_sys.h" #include "espconn.h" #include "osapi.h" #include "mem.h" #include "gpio.h" #include "os_type.h" #include "user_config.h" #include "user_interface.h" #include "driver/uart.h" #define user_procTaskPrio 0 #define user_procTaskQueueLen 1 void ICACHE_FLASH_ATTR network_init(); os_event_t user_procTaskQueue[user_procTaskQueueLen]; static void user_procTask(os_event_t *events); static volatile os_timer_t pulse_timer; static volatile os_timer_t debounce; LOCAL os_timer_t network_timer; static struct espconn global_udp_connect; // Connection struct (see espconn.h) static esp_tcp global_tcp; // TCP connect var (see espconn.h) static struct espconn global_tcp_connect; // Connection struct (see espconn.h) static uint8_t udp_conn_ok = FALSE; // Bool to know if udp connection set static uint8_t tcp_conn_ok = FALSE; // Bool to know if tcp connection set static uint16_t doppler_counter = 0; // Doppler counter static uint16_t pulse_count =0; char* itoa(int i, char b[]) // Convert Integer to ASCII!! { char const digit[] = "0123456789"; char* p = b; if(i<0){ *p++ = '-'; i *= -1; } int shifter = i; do{ //Move to where representation ends ++p; shifter = shifter/10; }while(shifter); *p = '\0'; do{ //Move back, inserting digits as u go *--p = digit[i%10]; i = i/10; }while(i); return b; } void debounce_func(void *arg) // // This routine is called on every INTERRUPT. the idea is to increment a counter as many times as needed // to record the pulse. Due to noise, we need to implement a debounce algorithm. // This is handled by the pulse timer func. { ETS_GPIO_INTR_DISABLE(); // Disable gpio interrupts uint16_t drop_copy = doppler_counter; // copy doppler val doppler_counter = 0; // not good! ETS_GPIO_INTR_ENABLE(); // Enable gpio interrupts if (drop_copy > 0) { pulse_count++; } } void pulse_timer_func(void *arg) { uint16_t drop_copy = pulse_count; // copy doppler val pulse_count = 0; // not good! if (GPIO_REG_READ(GPIO_OUT_ADDRESS) & BIT2) // If GPIO2 high { gpio_output_set(0, BIT2, BIT2, 0); // Set GPIO2 to LOW } else // Else { gpio_output_set(BIT2, 0, BIT2, 0); // Set GPIO2 to HIGH } // Send pulse counter if (tcp_conn_ok == TRUE) { uint8_t data[10] = " \x00\x00\x00\x00\x00"; itoa(drop_copy, data+1); espconn_sent(&global_tcp_connect, data, 10); os_printf("%u\n\r",drop_copy); } } void doppler_int_handler(int8_t key) { // Increment counter doppler_counter++; //Not that sure what this does yet and where the register is used for uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); //clear interrupt status GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(0)); } static void ICACHE_FLASH_ATTR tcpNetworkRecvCb(void *arg, char *data, unsigned short len) { struct espconn *tcpconn=(struct espconn *)arg; } static void ICACHE_FLASH_ATTR tcpNetworkConnectedCb(void *arg) { struct espconn *tcpconn=(struct espconn *)arg; espconn_regist_recvcb(tcpconn, tcpNetworkRecvCb); os_printf("TCP connected\n\r"); uint8_t data[20] = "Hello you!\r\n"; espconn_sent(tcpconn, data, 20); tcp_conn_ok = TRUE; } static void ICACHE_FLASH_ATTR tcpNetworkReconCb(void *arg, sint8 err) { os_printf("TCP reconnect\n\r"); tcp_conn_ok = FALSE; network_init(); } static void ICACHE_FLASH_ATTR tcpNetworkDisconCb(void *arg) { os_printf("TCP disconnect\n\r"); tcp_conn_ok = FALSE; network_init(); } static void ICACHE_FLASH_ATTR init_tcp_conn(void) { global_tcp_connect.type=ESPCONN_TCP; // We want to make a TCP connection global_tcp_connect.state=ESPCONN_NONE; // Set default state to none global_tcp_connect.proto.tcp=&global_tcp; // Give a pointer to our TCP var global_tcp_connect.proto.tcp->local_port=espconn_port(); // Ask a free local port to the API global_tcp_connect.proto.tcp->remote_port=888; // Set remote port (bcbcostam) global_tcp_connect.proto.tcp->remote_ip[0]=10; // Your computer IP global_tcp_connect.proto.tcp->remote_ip[1]=1; // Your computer IP global_tcp_connect.proto.tcp->remote_ip[2]=1; // Your computer IP global_tcp_connect.proto.tcp->remote_ip[3]=164; // Your computer IP espconn_regist_connectcb(&global_tcp_connect, tcpNetworkConnectedCb); // Register connect callback espconn_regist_disconcb(&global_tcp_connect, tcpNetworkDisconCb); // Register disconnect callback espconn_regist_reconcb(&global_tcp_connect, tcpNetworkReconCb); // Register reconnection function espconn_connect(&global_tcp_connect); // Start connection } void ICACHE_FLASH_ATTR network_start(void) { init_tcp_conn(); // Init tcp connection } void ICACHE_FLASH_ATTR network_check_ip(void) { struct ip_info ipconfig; os_timer_disarm(&network_timer); // Disarm timer wifi_get_ip_info(STATION_IF, &ipconfig); // Get Wifi info if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != 0) { network_start(); // Everything in order } else { os_printf("Waiting for IP...\n\r"); os_timer_setfn(&network_timer, (os_timer_func_t *)network_check_ip, NULL); os_timer_arm(&network_timer, 10000, 0); } } //Do nothing function static void ICACHE_FLASH_ATTR user_procTask(os_event_t *events) { os_delay_us(10); } // network init function void ICACHE_FLASH_ATTR network_init() { os_timer_disarm(&network_timer); os_timer_setfn(&network_timer, (os_timer_func_t *)network_check_ip, NULL); os_timer_arm(&network_timer, 1000, 0); } //Init function void ICACHE_FLASH_ATTR user_init() { uart_init(BIT_RATE_57600, BIT_RATE_57600); // Init UART @ 57600 bps ETS_GPIO_INTR_DISABLE(); // Disable gpio interrupts gpio_init(); // Initialize the GPIO subsystem. ETS_GPIO_INTR_ATTACH(doppler_int_handler, 0); // GPIO0 interrupt handler PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO0); // Set GPIO0 function gpio_output_set(0, 0, 0, GPIO_ID_PIN(0)); // Set GPIO0 as input GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(0)); // Clear GPIO0 status gpio_pin_intr_state_set(GPIO_ID_PIN(0), 1); // Interrupt on any GPIO0 edge PIN_PULLDWN_DIS(PERIPHS_IO_MUX_MTCK_U); // Disable pulldown PIN_PULLUP_EN(PERIPHS_IO_MUX_MTCK_U); // Enable pullup ETS_GPIO_INTR_ENABLE(); // Enable gpio interrupts os_timer_disarm(&pulse_timer); // Disarm led timer os_timer_setfn(&pulse_timer, (os_timer_func_t *)pulse_timer_func, NULL); // Setup led timer os_timer_arm(&pulse_timer, 1000, 1); // Arm led timer, 0.5sec, repeat os_timer_disarm(&debounce); // Disarm led timer os_timer_setfn(&debounce, (os_timer_func_t *)debounce_func, NULL); // Setup led timer os_timer_arm(&debounce, 100, 1); // Arm led timer, 0.5sec, repeat network_init(); // Init network timer char ssid[32] = "LightningStrikesTwice"; // Wifi SSID char password[64] = "97379039"; // Wifi Password struct station_config stationConf; // Station conf struct wifi_set_opmode(0x1); // Set station mode os_memcpy(&stationConf.ssid, ssid, 32); // Set settings os_memcpy(&stationConf.password, password, 64); // Set settings wifi_station_set_config(&stationConf); // Set wifi conf //wifi_status_led_install(13, PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); // Wifi LED status //Start os task system_os_task(user_procTask, user_procTaskPrio,user_procTaskQueue, user_procTaskQueueLen); os_printf("\n\rStartup done\n\r"); // Startup done }
-
Some useful comments
03/10/2015 at 13:19 • 0 commentsMonitoring TCP traffic on a Ubuntu box
http://manpages.ubuntu.com/manpages/utopic/man1/nc_openbsd.1.html
nc -l -p 888
- -l = Listen
- -p = Port
The Hardware
ESP8266 as the main controller
LM393 light sensor such as this one:
Desolder the sensor and remote mount it. It's just a cheap LDR. Plan is to stick it onto the LED on the meter.
Powersupply - Breadboard 3.3v 5v supply
Software Overview
Pulse Detect line to ESP8266 - I'm using GPIO in my sample circuit - but have to switch to GPIO 2 as it makes reprogramming tricky.
ESP8266 Interrrupt to pick up changes in light levels. Due to noise - need to decouple the ISR. So plan is to use a software debounce approach. A standard ISR will count the pulses - which might be several thousand per pulse. A second timer will operate every 10msec, and if the count of ISR pulses is > 1 then increment a second counter by 1. This will ensure that the circuit does not pick up noise.
The software will record pulses per minute. A minute timer will kick off and reset the pulse count. It will then open a TCPIP connection to
- The owl - report the pulse count for the last minute
The data will be written to a ESP File and stored for later retrieval as required.