Example #1
0
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);
    }
}
Example #2
0
static inline void update_state(void) {
	DHT22_DATA_t sensor_values;
	rtc_datetime_24h_t current_dt;
	readDHT22(&sensor_values);
	rtc_read(rtc, &current_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);
}