int16_t temp_get(temp_unit_t unit) { int16_t res; int16_t temp; /* Return if temp sensor driver not initialized */ if (temp_initialized == false) { return EOF; } /* Power up sensor */ TEMP_PORT |= (1 << TEMP_BIT_PWR); /* Init ADC and measure */ adc_init(ADC_CHAN_ADC4, ADC_TRIG_FREE_RUN, ADC_REF_AVCC, ADC_PS_128); adc_conversion_start(); while ((res = adc_result_get(ADC_ADJ_RIGHT)) == EOF ){ ; } #if MEASURE_ADC2 /* Measure external voltage supply, routed to ADC2 through a 470K/100K divider*/ /* AVCC is 3.3 volts if using external supply, else Vbat which will be lower */ /* Convert result to millivolts assuming AVCC is 3.3 volts, on battery it will be lower! */ adc_init(ADC_CHAN_ADC2, ADC_TRIG_FREE_RUN, ADC_REF_AVCC, ADC_PS_128); adc_conversion_start(); while ((ADC2_reading = adc_result_get(ADC_ADJ_RIGHT)) == EOF ){ ; } ADC2_reading = (ADC2_reading*((470+100)*3300UL))/(100*1024UL); #endif adc_deinit(); /* Re-init the adc for buttons. */ key_init(); /* Power down sensor */ TEMP_PORT &= ~(1 << TEMP_BIT_PWR); /* Get corresponding temperature from table */ if (unit == TEMP_UNIT_CELCIUS) { temp = find_temp(res, temp_table_celcius, sizeof(temp_table_celcius)/sizeof(int)) + TEMP_ZERO_OFFSET_CELCIUS; } else /*unit == TEMP_UNIT_FAHRENHEIT*/{ temp = find_temp(res, temp_table_fahrenheit, sizeof(temp_table_fahrenheit)/sizeof(int)) + TEMP_ZERO_OFFSET_FAHRENHEIT; } return temp; }
key_state_t key_state_get(void) { key_state_t ret = KEY_NO_KEY; int16_t res; adc_init(ADC_CHAN_ADC1, ADC_TRIG_FREE_RUN, ADC_REF_AVCC, ADC_PS_128); adc_conversion_start(); while ((res = adc_result_get(ADC_ADJ_RIGHT)) == EOF ){;} adc_deinit(); if (res>0x0370) { ret = KEY_NO_KEY; } else if (res>0x0280) { ret = KEY_DOWN; } else if (res>0x0180) { ret = KEY_LEFT; } else if (res>0x00C0) { ret = KEY_RIGHT; } else { ret = KEY_UP; } if (!(ENTER_PORT & (1<<ENTER_PIN))) { ret |= KEY_ENTER; } return ret; }
/** \brief Read current voltage * \return EOF on error */ double voltage_get() { int16_t result; /* Init ADC and measure */ adc_init(ADC_CHAN_ADC30, ADC_TRIG_FREE_RUN, ADC_REF_AVCC, ADC_PS_128); adc_conversion_start(); while ((result = adc_result_get(ADC_ADJ_RIGHT)) == EOF ){ ; } adc_deinit(); return 1.1 * (1024.0 / (double)result); }
static int16_t supply_voltage_read(void) { int16_t adc_res; // Read band gap voltage with Avcc as ref. Use result to calulate Vcc adc_init(ADC_CHAN_VBG, ADC_TRIG_FREE_RUN, ADC_REF_AVCC, ADC_PS_128); // wait for band gap voltage to stabilize delay_us(150); // read ADC adc_conversion_start(); while ((adc_res = adc_result_get(ADC_ADJ_RIGHT)) == EOF ){;} adc_deinit(); // Return battery voltage in mV return (int16_t)((1100L*1024L)/(long)adc_res); }
/** \brief Read current light's raw value * \return EOF on error */ int16_t sensor_light_get_raw() { int16_t result; if (!light_initialized) { light_init(); } /* Power up sensor */ LIGHT_PORT |= (1 << LIGHT_BIT); /* Init ADC and measure */ adc_init(ADC_CHAN_ADC4, ADC_TRIG_FREE_RUN, ADC_REF_AVCC, ADC_PS_128); adc_conversion_start(); while ((result = adc_result_get(ADC_ADJ_RIGHT)) == EOF ){ ; } adc_deinit(); /* Power down sensor */ LIGHT_PORT &= ~(1 << LIGHT_BIT); return result; }
/** Initalises the ADC registers for polling operation. */ adc_t adc_init (const adc_cfg_t *cfg) { adc_sample_t dummy; adc_dev_t *adc; const adc_cfg_t adc_default_cfg = { .bits = 10, .channel = 0, .clock_speed_kHz = 1000 }; if (adc_devices_num >= ADC_DEVICES_NUM) return 0; if (adc_devices_num == 0) { /* The clock only needs to be enabled when sampling. The clock is automatically started for the SAM7. */ mcu_pmc_enable (ID_ADC); adc_reset (); } adc = adc_devices + adc_devices_num; adc_devices_num++; adc->MR = 0; /* The transfer field must have a value of 2. */ BITS_INSERT (adc->MR, 2, 28, 29); if (!cfg) cfg = &adc_default_cfg; adc_config_set (adc, cfg); /* Note, the ADC is not configured until adc_config is called. */ adc_config (adc); #if 0 /* I'm not sure why a dummy read is required; it is probably a quirk of the SAM7. This will require a software trigger... */ adc_read (adc, &dummy, sizeof (dummy)); #endif return adc; } /** Returns true if a conversion has finished. */ bool adc_ready_p (adc_t adc) { return (ADC->ADC_ISR & ADC_ISR_DRDY) != 0; } /** Blocking read. This will hang if a trigger is not supplied (except for software triggering mode). */ int8_t adc_read (adc_t adc, void *buffer, uint16_t size) { uint16_t i; uint16_t samples; adc_sample_t *data; adc_config (adc); samples = size / sizeof (adc_sample_t); data = buffer; for (i = 0; i < samples; i++) { /* When the ADC peripheral gets a trigger, it converts all the enabled channels consecutively in numerical order. */ if (adc->trigger == ADC_TRIGGER_SW) adc_conversion_start (adc); /* Should have timeout, especially for external trigger. */ while (!adc_ready_p (adc)) continue; data[i] = ADC->ADC_LCDR; } /* Disable channel. */ ADC->ADC_CHDR = ~0; return samples * sizeof (adc_sample_t); }
PROCESS_THREAD(blink_process, ev, data) { static struct etimer et_blink; etimer_set(&et_blink, CLOCK_SECOND); PROCESS_BEGIN(); static char lux_value[6]; static char lux_value2[6]; static char raw_value[6]; static char raw_value2[6]; static char temperature_val[6]; static uint16_t adc_data=0; static uint16_t adc_data2=0; static float adc_lux=0; static float adc_lux2=0; static float measured_temp=0; // static int blinks = 0; ssd1306_clear(); ssd1306_set_page_address(0); ssd1306_set_column_address(2); ssd1306_write_text("Lumen in Lux:"); ssd1306_set_page_address(1); ssd1306_set_column_address(2); ssd1306_write_text("Raw ADC out :"); ssd1306_set_page_address(2); ssd1306_set_column_address(2); ssd1306_write_text("Ambient Temperature measured:"); while(1) { PROCESS_WAIT_EVENT(); if (ev==PROCESS_EVENT_TIMER) { DDRB |=(1<<PORTB4); PORTB ^= (1<<PORTB4); adc_init(); adc_data=get_adc(0); adc_lux=adc_data*0.9765625; /* amps=adc_volt/10000.0; microamps=amps/1000000; lux_data=microamps*2; */ itoa(adc_lux, lux_value, 10); ssd1306_set_page_address(0); ssd1306_set_column_address(73); ssd1306_write_text(lux_value); itoa(adc_data, raw_value, 10); ssd1306_set_page_address(1); ssd1306_set_column_address(73); ssd1306_write_text(raw_value); adc_init_full(ADC_CHAN_ADC0, ADC_TRIG_FREE_RUN, ADC_REF_AVCC, ADC_PS_64); adc_conversion_start(); adc_lux2=adc_data2*0.9765626; itoa(adc_lux2, lux_value2, 10); ssd1306_set_page_address(0); ssd1306_set_column_address(95); ssd1306_write_text(lux_value2); itoa(adc_data2, raw_value2, 10); ssd1306_set_page_address(1); ssd1306_set_column_address(95); ssd1306_write_text(raw_value2); measured_temp=ReadTempVal(); itoa(measured_temp, temperature_val, 10); ssd1306_set_page_address(2); ssd1306_set_column_address(95); ssd1306_write_text(temperature_val); } } PROCESS_END(); }
void vControl ( void *pvParameters ) { portTickType xLastWakeTime; signed char valx, valy; unsigned char ls, rs, lb, rb; can_frame_t out_frame; can_frame_t in_frame; out_frame.id = 1; out_frame.dlc = 6; xLastWakeTime = xTaskGetTickCount (); /* Button init */ buttons_init (); /* FSM init */ fsm_init (); /* CAN init */ can_init (); /* ADC init */ adc_init ( ctrlNUM_ADC_VALUES ); /* Touch init */ touch_init ( 30, 30, 30, 30 ); while (1) { vTaskDelayUntil ( &xLastWakeTime, ctrlTASK_FREQUENCY ); if ( adc_conversion_complete () == pdTRUE ) { adc_disable (); adc_get_value ( &valx, 0 ); adc_get_value ( &valy, 0 ); touch_measure ( &ls, &rs, &lb, &rb ); out_frame.data[0] = valx; out_frame.data[1] = valy; out_frame.data[2] = ls; out_frame.data[3] = rs; out_frame.data[4] = lb; out_frame.data[5] = rb; if (fsm_get_state() == ST_PLAY) { can_transmit (&out_frame); } can_receive (&in_frame, 0); if (in_frame.data[0] == GAME_SENSOR_TRIGGERED) { // TODO: set triggered state fsm_event_t *event = pvPortMalloc (sizeof (fsm_event_t)); event->type = EV_STOP; event->ptr = NULL; fsm_event_put (event, portMAX_DELAY); in_frame.data[0] = 0; } else if (in_frame.data[0] == GAME_SENSOR_CLEARED) { // TODO: set cleared state in_frame.data[0] = 0; } adc_enable (); adc_conversion_start (); } fsm_update (); } }