void main_loop(void* pvParameters) { int loopcount = 0; #define SHOW_DEBUG() 0 //((my_state == RUNNING) && (loopcount == 0)) #define SPI_SCLK 4 #define SPI_MISO 27 #define SPI_MOSI 2 #define SPI_CS GPIO_NUM_16 #define SPI_CE GPIO_NUM_17 int power_left = 0; int power_right = 0; #if 0 int left_x_zero = 512; int left_y_zero = 512; #endif int right_x_zero = 512; int right_y_zero = 512; bool first_reading = true; auto last_packet = xTaskGetTickCount(); const int NOF_BATTERY_READINGS = 100; int32_t battery_readings[NOF_BATTERY_READINGS]; int battery_reading_index = 0; for (int i = 0; i < NOF_BATTERY_READINGS; ++i) battery_readings[i] = 0; int max_power = 255; int count = 0; bool led_state = false; auto last_led_flip = xTaskGetTickCount(); bool is_halted = false; RF24 radio(SPI_CE, SPI_CS); assert(radio_init(radio)); while (1) { ++loopcount; if (loopcount >= 100) loopcount = 0; // if there is data ready if (radio.available()) { last_packet = xTaskGetTickCount(); ForwardAirFrame frame; // Fetch the payload, and see if this was the last one. while (radio.available()) radio.read(&frame, sizeof(frame)); if (frame.magic != ForwardAirFrame::MAGIC_VALUE) { printf("Bad magic value; expected %x, got %x\n", ForwardAirFrame::MAGIC_VALUE, frame.magic); continue; } if (!check_crc(frame)) { printf("Bad CRC\n"); continue; } // Echo back tick value so we can compute round trip time radio.stopListening(); ReturnAirFrame ret_frame; ret_frame.magic = ReturnAirFrame::MAGIC_VALUE; ret_frame.ticks = frame.ticks; #if 0 battery_readings[battery_reading_index] = motor_get_battery(motor_device); ++battery_reading_index; if (battery_reading_index >= NOF_BATTERY_READINGS) battery_reading_index = 0; int n = 0; int32_t sum = 0; for (int i = 0; i < NOF_BATTERY_READINGS; ++i) if (battery_readings[i]) { sum += battery_readings[i]; ++n; } // Round to nearest 0.1 V to prevent flickering ret_frame.battery = n ? 100*((sum/n+50)/100) : 0; #endif set_crc(ret_frame); radio.write(&ret_frame, sizeof(ret_frame)); radio.startListening(); frame.right_x = 1023 - frame.right_x; // hack! #define PUSH(bit) (is_pushed(frame, bit) ? '1' : '0') #define TOGGLE(bit) (is_toggle_down(frame, bit) ? 'D' : (is_toggle_up(frame, bit) ? 'U' : '-')) const int rx = frame.right_x - right_x_zero; const int ry = frame.right_y - right_y_zero; // Map right pot (0-255) to pivot value (20-51) const int pivot = frame.right_pot*2; // Map left pot (0-255) to max_power (20-255) max_power = static_cast<int>(20 + (256-20)/256.0*frame.left_pot); compute_power(rx, ry, power_left, power_right, pivot, max_power); ++count; if (count > 10) { count = 0; printf("max %d\n", max_power); printf("L %4d/%4d R %4d/%4d (%d/%d) P %3d/%3d Push %c%c%c%c" " Toggle %c%c%c%c" " Power %d/%d\n", (int) frame.left_x, (int) frame.left_y, (int) frame.right_x, (int) frame.right_y, rx, ry, int(frame.left_pot), int(frame.right_pot), PUSH(0), PUSH(1), PUSH(2), PUSH(3), TOGGLE(0), TOGGLE(1), TOGGLE(2), TOGGLE(3), power_left, power_right); #if 0 if (is_toggle_up(frame, 3)) signal_control_lights(signal_device, true, true); else if (is_toggle_down(frame, 3)) signal_control_lights(signal_device, true, false); else signal_control_lights(signal_device, false, true); #endif } //!!set_motors(power_left, power_right); is_halted = false; #if 0 if (is_pushed(frame, 0)) signal_play_sound(signal_device, -1); #endif } else { // No data from radio const auto cur_time = xTaskGetTickCount(); if ((cur_time - last_packet > max_radio_idle_time) && !is_halted) { is_halted = true; printf("HALT: Last packet was seen at %d\n", last_packet); first_reading = true; set_motors(0, 0); } } // Change LED state every 3 seconds const auto cur_time = xTaskGetTickCount(); if (cur_time - last_led_flip > 3000/portTICK_PERIOD_MS) { last_led_flip = cur_time; led_state = !led_state; gpio_set_level(GPIO_INTERNAL_LED, led_state); } vTaskDelay(1/portTICK_PERIOD_MS); //xTaskNotifyWait(0, 0, NULL, 1); } }
static inline void update_state(void) { DHT22_DATA_t sensor_values; rtc_datetime_24h_t current_dt; readDHT22(&sensor_values); rtc_read(rtc, ¤t_dt); event_t* events = get_events(); long start_secs; long current_secs; uint8_t i = 0; uint8_t flag = 0; state.temperature = sensor_values.raw_temperature; state.humidity = sensor_values.raw_humidity; state.light = adc_read(PHOTORESISTOR); datetime = (datetime_t ) { .year = current_dt.year, .month = current_dt.month, .date = current_dt.date, .hour = current_dt.hour, .minute = current_dt.minute, .second = current_dt.second }; current_secs = get_seconds((instant_t ) { datetime.hour, datetime.minute, datetime.second }); // recorro eventos para ver si tengo que activar relays for (i = 0; i < MAX_EVENTS; i++) { if (events[i].enabled) { start_secs = get_seconds(events[i].start); if (start_secs < current_secs && (start_secs + events[i].duration) > current_secs) { flag |= (1 << events[i].target); /* activar el evento */ } } } // si activaron coil, estamos dentro de un evento o presionaron pulsador for (uint8_t i = 0; i < NUMBER_OF_COILS; i++) { if (relays & (1 << i) || (flag & (1 << i)) || is_pushed()) { enable_relay(i); } else { disable_relay(i); } } if (ticks >= get_log_interval()) { update_log_filename(); /* si cambio el dia y hay que hacer roll del archivo */ //yyyyMMddhhmmss light humidity temperature f_printf(&log_file, "%04d%02d%02d%02d%02d%02d\t%d\t%d\t%d\t%d\t%d\n", datetime.year, datetime.month, datetime.date, datetime.hour, datetime.minute, datetime.second, state.light, state.humidity, state.temperature, is_relay_enabled(0), is_relay_enabled(1)); f_sync(&log_file); ticks = 0; } } void timer0_callback() { ticks++; LED_PORT ^= _BV(LED); }