extern int __analogRead(uint8_t pin)
{
  if (pin == 0)
    return system_adc_read();

  return 0;
}
Beispiel #2
0
/**
 @brief return system_adc_read scaled to a float 
  T_OUT pin is connected to the junction of a voltage divider R1 and R2
  R1 is connected to VCC
  R2 is connected to ground
  T_OUT is connected to the junction of R1 and R2
//FIXME T_OUT has a loading value
 @return float
*/
float adc_read()
{
	uint16_t system_adc_read(void);
	// system adc read returns 0 .. 1023
	// range 0 .. 1.0V
	return( ((float)system_adc_read()) * VSCALE );
}
Beispiel #3
0
int ICACHE_FLASH_ATTR LightSW_ReadIntensityCounts(void)
{
	int i, valueAcc = 0;
	for (i = 0; i < MEASURE_SAMPLES; i++)
		valueAcc += system_adc_read();
	return (int) valueAcc / MEASURE_SAMPLES;
}
Beispiel #4
0
// Lua: read(id) , return system adc
static int adc_sample( lua_State* L )
{
    unsigned id = luaL_checkinteger( L, 1 );
    MOD_CHECK_ID( adc, id );
    unsigned val = 0xFFFF & system_adc_read();
    lua_pushinteger( L, val );
    return 1;
}
// Read ADC call back
LOCAL void ICACHE_FLASH_ATTR
read_adc(void* arg)
{
    // Read ADC
    uint16_t value = system_adc_read();
    os_printf("ADC: %d\n", value);
    double temperature = ((double)value / 1024.0) * 330;
    os_printf("Temperature: %ld C\n", temperature);
}
Beispiel #6
0
static void ICACHE_FLASH_ATTR xmitWordCb(void) {
	os_printf("ADC = %d, ", level = system_adc_read());
	xmit.data[3] = 0xaa;
	xmit.data[2] = level >> 8;
	xmit.data[1] = level & 0xff;
	xmit.data[0] = xmit.data[3] + xmit.data[2] + xmit.data[1];
	os_printf("%08lx\n", xmit.word);
	wordBitCount = 34; // Start xmit
}
Beispiel #7
0
STATIC mp_obj_t pyb_adc_read(mp_obj_t self_in) {
    pyb_adc_obj_t *adc = self_in;

    if (adc->isvdd) {
        return mp_obj_new_int(system_get_vdd33());
    } else {
        return mp_obj_new_int(system_adc_read());
    }
}
Beispiel #8
0
void loop()
{
	digitalWrite(ledPower,LOW); // power on the LED
	delayMicroseconds(delayTime);

	dustVal = system_adc_read(); // read the dust value via A0 pin
	delayMicroseconds(delayTime2);

	digitalWrite(ledPower,HIGH); // turn the LED off
	delayMicroseconds(offTime);
	  
	delay(3000);
	serial_printf("dush val = %d\r\n", dustVal);
}
Beispiel #9
0
static uint16 custom_adc_read(void){
	uint16 result = system_adc_read();

	if (getConfig()->ADCModeFlags & CFG_ADC_DECODER_OUT_ON){
		//do output to decoder
		//we need only 3 most significant bits
		//ESP8266 ADC max value is 1024, which give us 11th bit on max value. We ignore this case
		if (result == 1024){
			decoderSet(7);
		}else{
			decoderSet(result>>7);
		}
	}

	return result;
}
Beispiel #10
0
void on_mqtt_data(uint32_t *args, const char *topic, uint32_t topic_len,
		  const char *data, uint32_t data_len)
{
	char cmd[256];

	if (data_len < sizeof(cmd)) {
		os_memcpy(cmd, data, data_len);
		cmd[data_len] = '\0';

		/* echo back the message */
		dmesg(cmd);

		if (strcmp("SCAN", cmd) == 0) {
			wifi_station_scan(NULL, on_scan_ready);
		} else if (strcmp("ADC_READ", cmd) == 0) {
			uint16 adc_in = system_adc_read();
			dmesg("adc_in=%hu", (unsigned short)adc_in);
		}
	}
}
//Read battery, enable PWM etc.
void ICACHE_FLASH_ATTR io_init() {
	int x;
	//Between io_init_main and io_init, the firmware will re-initialize some gpios. Re-re-initialize them.
	gpioInit();
#if NEW_BUTTON
	//We can only measure the battery status with the nightlight feature on. Nightlight has to be done with pwm off.
	enableNightlight(1);

	os_delay_us(1000);
	x=system_adc_read();
	//AD is 1024 at Tout=1V. There is an (800K+1M)/200K resistor divider to lower the battery voltage into that range.
	//This means that the Tout value of 1024 is reached at a voltage of 10 volt.
	batteryVoltageMv=(x*10000)/1024;
	
	//Okay, initialize PWM.
	io_pwm_init();
#else
	x=system_get_vdd33();
	batteryVoltageMv=(x*1000)/1024;
#endif
	os_printf("Battery: %d mv\n", batteryVoltageMv);
}
Beispiel #12
0
LOCAL void ICACHE_FLASH_ATTR adc_read(char *response, bool poll) {
	char data[WEBSERVER_MAX_VALUE];
	char poll_str[WEBSERVER_MAX_VALUE];
	
	poll = true;
	state = system_adc_read();
	
	if (poll) {
		json_poll_str(poll_str, adc_refresh / 1000, adc_each, adc_threshold);
	} else {
		poll_str[0] = '\0';
	}
	
	json_data(
		response, ESP8266, OK_STR, 
		json_sprintf(
			data,
			"\"ADC\" : {\"Value\" : %d %s}",
			state,
			poll_str
		),
		NULL
	);
}
Beispiel #13
0
uint16_t get_adc()
{
	return system_adc_read();
}
Beispiel #14
0
//this function is called every 50ms. it sends the appropriate command to the quadcoper
 LOCAL void ICACHE_FLASH_ATTR
 user_udp_send(void)
 {
	 char DeviceBuffer[40] = {0};
	 char hwaddr[6];
	 struct ip_info ipconfig;
	 unsigned long pitch;
	 unsigned long speed;
	 const char udp_remote_ip[4] = { 255, 255, 255, 255}; 
	 os_memcpy(user_udp_espconn.proto.udp->remote_ip, udp_remote_ip, 4); // ESP8266 udp remote IP need to be set everytime we call espconn_sent
	 user_udp_espconn.proto.udp->remote_port = 5556;  // ESP8266 udp remote port need to be set everytime we call espconn_sent

	 wifi_get_macaddr(STATION_IF, hwaddr);
 	
	//detect adc button push, and increase state
	if(system_adc_read() < 100 & adc_read_last > 100){
		flystate = (flystate + 1)%FLYSTATECOUNT;
	}

	//initialise navigational data if necessary
	if(flystate == FLYSTATE_INITNAV){
		os_sprintf(DeviceBuffer, "AT*CONFIG=\"general:navdata_demo\",\"TRUE\"\\r");
		//os_sprintf(DeviceBuffer, "AT*CONFIG=%d%s%s\r", "\"general:navdata_demo\"","\"TRUE\"");
		flystate++;

	//acknowledge something
	}else if(flystate == FLYSTATE_ACK1){
		os_sprintf(DeviceBuffer, "AT*CTRL=0\r");
		flystate++;

	// tell drone its flying with outdoor shell
	}else if(flystate == FLYSTATE_OUTDOOR){
		os_sprintf(DeviceBuffer, "AT*CONFIG=%d,%s,%s\r", sequence++, "\"control:flight_without_shell\"","\"TRUE\"");
		flystate++;
		
	//AT*CONFIG=605,"control:flight_without_shell","TRUE"
	}else if(flystate == FLYSTATE_OUTDOORSHELL){
		os_sprintf(DeviceBuffer, "AT*CONFIG=%d,%s,%s\r", sequence++, "\"control:outdoor\"","\"TRUE\"");
		flystate++;
		
	// takeoff!
	}else if(flystate == FLYSTATE_TAKEOFF){
		os_sprintf(DeviceBuffer, "%s%d%s\r", ATREF, sequence++, TAKEOFF);
		needsCalibration = 1;

	//operate manual control
	}else if(flystate == FLYSTATE_MANUAL1 | flystate == FLYSTATE_MANUAL2){
		forward = !GPIO_INPUT_GET(5);
		left = !GPIO_INPUT_GET(0);
		right = !GPIO_INPUT_GET(4);
		
		if(needsCalibration){
			os_sprintf(DeviceBuffer, "AT*CALIB=%d,%d\r", sequence++, 0);
			needsCalibration = 0;
		}else{
			speed = forward*neg50asSingle;
			//determine values frim input
			if(left & !right)
				pitch = neg50asSingle;	
			else if(right & !left)
				pitch = d50asSingle;
			else
				pitch = 0;
			os_sprintf(DeviceBuffer, "%s%d,%d,%d,%d,%d,%d\r", ATPCMD, sequence++, (left || right || forward), 
				0, speed,0, pitch);
		//os_sprintf(DeviceBuffer, "%s" MACSTR "!" , ESP8266_MSG, MAC2STR(hwaddr));
		}

	//otherwse perform pathing with reference to GPS data
	}else if(flystate == FLYSTATE_AUTOMATIC)
		os_sprintf(DeviceBuffer, "AT*COMWDG=%d\r", sequence++);

	//send ftrim if grounded
	else if(flystate == FLYSTATE_GROUNDED_START)
		os_sprintf(DeviceBuffer, "AT*FTRIM=%d\r", sequence++);

	//send land command
	else if(flystate == FLYSTATE_GROUNDED_END)
		os_sprintf(DeviceBuffer, "%s%d%s\r", ATREF, sequence++, LAND);
	
	
	os_printf("LAT0: %d LONG0: %d, TIME0: %d LAT1: %d LONG1: %d TIME1: %d\n", (int)(getGPS(0, RMC_LAT)*1000), (int)(getGPS(0, RMC_LONG)*1000), (int)getGPS(0, RMC_TIME), (int)(getGPS(1, RMC_LAT)*1000), (int)(getGPS(1, RMC_LONG)*1000), (int)getGPS(1, RMC_TIME));
	//os_printf("TEST: %d\n", (int)10.0);

	//update adc_read_last
 	adc_read_last = system_adc_read();	
	//send the buffer
 	espconn_sent(&user_udp_espconn, DeviceBuffer, os_strlen(DeviceBuffer));
}
Beispiel #15
0
/*
 * An ADC measurement is made every time this timer triggers.
 * The ADC input is connected to a:
 * SparkFun MEMS Microphone Breakout - INMP401 (ADMP401)
 * https://www.sparkfun.com/products/9868
 *
 * This callback also contains the logic that simulates an
 * equalizer by changing the LED colors of a ws2812 LED strip
 */
void softwareTimerCallback(void *arg)
{
    /* ====================================== */
	/* ADC	                         	  	  */
	/* ====================================== */

	uint16 i;

    /* Current ADC value (volume level of the most recent ADC measurement)*/
	uint16 adc_value;

	/* Previous ADC value (volume level of previous ADC capture)*/
	static uint16 prev_adc_value;

	/* The absolute value of the difference of the current and previous ADC values */
	uint16 abs_val_diff = 0;

	/* Color in RGB space */
	rgb my_rgb;

	/* Color in HSV space */
	hsv my_hsv;

	/* TODO: make rainbow when no volume */
	static int count = 0;

	/* defines the number of ws2812 LEDs */
	static int num_leds = 30;

	/* Changes of volume below the threshold are ignored */
	static int threshold = 20;

	/* Controls the gradual LED color change animation */
	static bool lock = false;

	/* Controls the heatmap of the LEDs */
	static int heatmap = 0;

	/* Buffer that stores the colors of each LED in the strip */
	uint8_t led_out[num_leds * 3];

	const uint16 red_up_num_cycles = 25;
	static bool count_up = true;

	/* Init saturation and value for HSV color */
	my_hsv.s = 1.0;
	my_hsv.v = 0.1;

	/* Read ADC */
	adc_value = system_adc_read();

	/* Calculate the absolute value of the previous and current ADC values */
	abs_val_diff = ( adc_value > prev_adc_value ) ? adc_value - prev_adc_value : prev_adc_value - adc_value;

	/* Save adc_value */
	prev_adc_value = adc_value;

	/* Gradual color change animation taking place?
	 * OR
	 * Is the measured value larger than the last value
	 * that triggered the animation?*/
	if ( lock == false || abs_val_diff > heatmap )
	{
#if 0
		os_printf("\r\nheatmap: %d", heatmap);
#endif

		/* Is the measured value larger than the threshold? */
		if ( abs_val_diff >= threshold )
		{
			/* Trigger detected! Start animation! */
			lock = true;

			/* Save the value that triggered the animation */
			heatmap = abs_val_diff;

			/* Reset important variables used in the animation */
			count_up = true;
			count = 0;
		}
	}
	else
	{
		/* No, then continue with animation */
	}


	/************************************
	 * GRADUAL LED COLOR CHANGE ANIMATION
	 ************************************/

	/* Enter only if an animation was triggered above */
	if ( lock == true )
	{
		/* Are we 'heating up' or 'cooling down'? */
		if ( count_up == true )
		{
			/* Heat up (faster than cooling down) */
			count += 3;

			count_up = (count >= red_up_num_cycles) ? false : true ;
		}
		else
		{
			/* Cool down */
			count--;

			if ( count <= 2 )
			{
				/* Stop gradual color change */
				lock = false;
			}
		}

#if 0
		os_printf("\r\ncount: %d", count);
#endif

		/* Set color for each LED */
		for (i = 0; i < num_leds; i++)
		{
			if ( i == 0 )
			{
				/* The first LED is always set to blue */
				my_hsv.h = 240.0;
			}
			else
			{
				/* Decrease hue depending on the change in volume */
				my_hsv.h = (uint16)my_hsv.h - (uint16)(heatmap * 0.005 * count);
			}


			/* Clip hue if below 0 */
			my_hsv.h = my_hsv.h < 0 ? 0 : my_hsv.h;

			/* Convert color from HSV to RGB space */
			my_rgb = hsv2rgb(my_hsv);

			/* Store RGB color in the output buffer */
			led_out[i * 3 + 0] = my_rgb.g * 255;
			led_out[i * 3 + 1] = my_rgb.r * 255;
			led_out[i * 3 + 2] = my_rgb.b * 255;
		}

		ws2812_push(led_out, sizeof(led_out));

	#if 0
			os_printf("\r\nG R B: %x %x %x", led_out[0], led_out[1],led_out[2]);
	//		os_printf("\r\nhue: %d", (int)my_hsv.h);
	#endif

	#if 0
	//	os_printf("\r\nsystem_adc_read: %x", adc_value);
	//	os_printf("\r\ndiff_abs_val: %x", diff_abs_val);
	#endif
	}

	return;
}
Beispiel #16
0
uint32_t sj_adc_read(int pin) {
  (void) pin;
  return 0xFFFF & system_adc_read();
}
Beispiel #17
0
JsVarFloat jshPinAnalog(Pin pin) {
  os_printf("> ESP8266: jshPinAnalog: %d\n", pin);
	return (JsVarFloat) system_adc_read();
}
static int do_adc (int argc, const char* const* argv)
{
	console_printf("%d\n", system_adc_read());
	return 0;
}
Beispiel #19
0
int adc_read_value(port_t *port) {
    return system_adc_read() * 1000 / 1024;
}
/**
 @brief test task
  Runs corrected cube demo from Sem
  Optionally wireframe Earh viewer
 @return void
*/
LOCAL void user_task(void)
{
	uint32_t time1,time2;
	uint8_t red, blue,green;
	long timer = 0;
	uint16 system_adc_read(void);
	extern uint8_t ip_msg[];
	time_t sec;
	char buffer[256];


	

#ifdef WIRECUBE
	V.x = degree;
	V.y = degree;
	V.z = degree;
// Cube points were defined with sides of 1.0 
// We want a scale of +/- w/2
	wire_draw(windemo, cube_points, cube_edges, &V, windemo->w/2, windemo->h/2, dscale, 0);
	//wire_draw(windemo, cube_points, cube_edges, &V, windemo->w/2, windemo->h/2, dscale, 0);
#endif

#ifdef CIRCLE
	rad = dscale; // +/- 90
    tft_drawCircle(windemo, windemo->w/2, windemo->h/2, rad ,0);
	Display bounding circle that changes color around the cube
	if(dscale_inc < 0.0)
	{
		red = 255;
		blue = 0;
		green = 0;
	}
	else
	{
		red = 0;
		blue = 255;
		green = 0;
	}
	// RGB - YELLOW
    tft_drawCircle(windemo, windemo->w/2, windemo->h/2, dscale, tft_color565(red,green,blue));
#endif

    degree += deg_inc;
    dscale += dscale_inc;

	if(degree <= -360)
		deg_inc = 4;
	if(degree >= 360)
		deg_inc = -4;

    if(dscale < dscale_max/2)
	{
	   dscale_inc = -dscale_inc;
	}
    if(dscale > dscale_max)
	{
	   dscale_inc = -dscale_inc;
	}


#ifdef WIRECUBE
	V.x = degree;
	V.y = degree;
	V.z = degree;
	//time1 = system_get_time();
	wire_draw(windemo, cube_points, cube_edges, &V, windemo->w/2, windemo->h/2, dscale, ILI9341_WHITE);
	//wire_draw(windemo, cube_points, cube_edges, &V, windemo->w/2, windemo->h/2, dscale, ILI9341_WHITE);
	//time2 = system_get_time();
#endif


// Get system voltage 33 = 3.3 volts
	adc_sum += system_adc_read();
	//adc_sum += system_get_vdd33();

	// FIXME atomic access
	if(++adc_count == 10)
	{
		voltage = ((double) adc_sum / 100.0); 
		adc_count = 0;
		adc_sum = 0;
	}

	// DEBUG_PRINTF("Degree: %d \r\n",(int)degree);
	// cube redraw count
	count += 1;
	tft_set_font(winstats,0);
	tft_setpos(winstats,ip_xpos,ip_ypos);
	tft_printf(winstats,"%-26s\n", ip_msg);
	if(!signal_loop--)
	{
		signal_loop = 100;
		tft_printf(winstats,"CH:%02d, DB:-%02d\n", 
			wifi_get_channel(),
			wifi_station_get_rssi());
		signal_loop = 0;
	}
	tft_setpos(winstats,xpos,ypos);
	tft_printf(winstats,"Heap: %d\n", system_get_free_heap_size());
	tft_printf(winstats,"Iter:% 9ld, %+7.2f\n", count, degree);
	
	// NTP state machine
	ntp_setup();

	// get current time
	time(&sec);

	tft_printf(winstats,"Volt:%2.2f\n%s\n", (float)voltage, ctime(&sec));
	
#ifdef NETWORK_TEST
	poll_network_message(wintest);
#endif

// Buffered get line uses interrupts and queues
	if(uart0_gets(buffer,255))
	{
		DEBUG_PRINTF("Command:%s\n",buffer);
		if(!fatfs_tests(buffer))
		{
			if(!user_tests(buffer))
			{
				DEBUG_PRINTF("unknow command: %s\n", buffer);
			}
		}
	}
}
Beispiel #21
0
/******************************************************************************
 * FunctionName : udp_test_port_recv
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
udp_test_port_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
{
	uint8 usrdata[32];
    if (p == NULL)  return;
    if(p->tot_len < 2) {
        pbuf_free(p);
    	return;
    }
    uint16 length = mMIN(p->tot_len, sizeof(usrdata)-1);
#if DEBUGSOO > 0
    os_printf("udp " IPSTR ":%u [%d]\n", IP2STR(addr), port, p->tot_len);
#endif
    length = pbuf_copy_partial(p, usrdata, length, 0);
    pbuf_free(p);

    uint8 *pudpbuf = (uint8 *)os_zalloc(udpbufsize+1);
    if(pudpbuf == NULL) return;
    uint16 udpbuflen = 0;
    int x = 0;
    if(length>2) x = atoi((char *)&usrdata[2]);
    if ((length>1)&&(usrdata[1]=='?')) switch(usrdata[0])
    {
      case 'M':
          system_print_meminfo();
      case 'A':
        {
          udp_puts("\nChip_id: %08x Flash_id: %08x\nsys_time:%08x ADC:%d\n", system_get_chip_id(), spi_flash_get_id(), system_get_time(), system_adc_read());
          struct softap_config wiconfig;
          wifi_softap_get_config(&wiconfig);
          udp_puts("OPMode:%u SSID:'%s' Pwd:'%s' Ch:%u Authmode:%u MaxCon:%u Phu:%u ACon:%u\n", wifi_get_opmode(), wiconfig.ssid, wiconfig.password, wiconfig.channel, wiconfig.authmode, wiconfig.max_connection, wifi_get_phy_mode(), wifi_station_get_auto_connect());
          udp_puts("Connect status:%u\n", wifi_station_get_connect_status());
        };
      case 'I':
          udp_puts("heapsize: %d\n", system_get_free_heap_size() + udpbufsize);
          udpbuflen += print_udp_psc(pudpbuf+udpbuflen, udpbufsize-udpbuflen);
          udpbuflen += print_tcp_psc(pudpbuf+udpbuflen, udpbufsize-udpbuflen);
          udpbuflen += chow_tcp_connection_info(pudpbuf+udpbuflen, udpbufsize-udpbuflen);
          break;
      case 'H':
          udp_puts("heapsize: %d\n", system_get_free_heap_size() + udpbufsize);
          break;
      case 'U':
          udp_puts("heapsize: %d\n", system_get_free_heap_size() + udpbufsize);
          udpbuflen += print_udp_psc(pudpbuf+udpbuflen, udpbufsize-udpbuflen);
          break;
      case 'T':
          udp_puts("heapsize: %d\n", system_get_free_heap_size() + udpbufsize);
          udpbuflen += print_tcp_psc(pudpbuf+udpbuflen, udpbufsize-udpbuflen);
          break;
#ifdef USE_SRV_WEB_PORT
      case 'S':
          udp_puts("heapsize: %d\n", system_get_free_heap_size() + udpbufsize);
          udpbuflen += chow_tcp_connection_info(pudpbuf+udpbuflen, udpbufsize-udpbuflen);
          break;
#endif
      case 'R':
          system_restart();
          break;
      case 'P':
          udp_puts("system_set_os_print(%u)\n", x);
          system_set_os_print(x);
          break;
      case 'O':
          udp_puts("wifi_set_opmode(%u):%u\n", x, wifi_set_opmode(x));
          break;
      case 'B':
          udp_puts("wifi_station_set_auto_connect(%u):%u\n", x, wifi_station_set_auto_connect(x));
          break;
      case 'D':
          switch(x) {
          case 0:
              udp_puts("wifi_station_dhcpc_start:%u\n", wifi_station_dhcpc_start());
              break;
          case 1:
              udp_puts("wifi_station_dhcpc_stop:%u\n", wifi_station_dhcpc_stop());
              break;
          case 2:
              udp_puts("wifi_softap_dhcps_start:%u\n",wifi_softap_dhcps_start());
              break;
          case 3:
              udp_puts("wifi_softap_dhcps_stop:%u\n", wifi_softap_dhcps_stop());
              break;
          default:
              udp_puts("D(%u)?\n", x);
          }
          break;
          case 'F':
        	  if(flashchip != NULL) {
        		  udp_puts("FlashID: 0x%08x\nChip size: %d\nBlock size: %d\nSector size: %d\nPage size: %d\nStatus mask: 0x%08x\n", flashchip->deviceId, flashchip->chip_size, flashchip->block_size, flashchip->sector_size, flashchip->page_size, flashchip->status_mask );
        		  udp_puts("Real Flash size: %u\n", spi_flash_real_size());
        	  }
        	  else udp_puts("Unknown Flash type!\n");
              break;
          case 'E':
        	  udp_puts("wifi_set_sleep_type(%d):%u\n", x, wifi_set_sleep_type(x));
        	  break;
          case 'G':
        	  udp_puts("g_ic = %p\n", &g_ic);
        	  break;
      default:
          udp_puts("???\n");
    }
    if(udpbuflen) {
    	struct pbuf *z = pbuf_alloc(PBUF_TRANSPORT, udpbuflen, PBUF_RAM);
    	if(z != NULL) {
        	err_t err = pbuf_take(z, pudpbuf, udpbuflen);
        	os_free(pudpbuf);
        	if(err == ERR_OK) {
        	    udp_sendto(upcb, z, addr, port);
        	}
      	    pbuf_free(z);
        	return;
    	}
    }
    os_free(pudpbuf);
}
Beispiel #22
0
JsVarFloat jshPinAnalog(Pin pin) {
	jsiConsolePrintf("ESP8266: jshPinAnalog: %d\n", pin);
	return (JsVarFloat) system_adc_read();
} // End of jshPinAnalog
Beispiel #23
0
void ICACHE_FLASH_ATTR updatePressure(void) {
	uint16 newPressure = system_adc_read();
	if (!overridePressure) {
		currentPressure = (currentPressure * 9 + newPressure) / 10; // Average over 1 second
	}
}