#include #include #include "freertos/FreeRTOS.h" #include "esp_adc/adc_oneshot.h" #include "nvs_flash.h" #include "esp_event.h" #include "esp_netif.h" #include "esp_wifi.h" #include "esp_log.h" #include "esp_err.h" #include "esp_mac.h" #include "esp_now.h" #include "sensors_data.h" #include "config.h" const char *JTAG = "Joystick"; //const char *TAG = "ESP-NOW_Transmitter"; esp_now_peer_info_t devices; adc_oneshot_unit_handle_t adc_xy_handle; sensors_data_t buffer; static int x, y; // Joystick x- and y- axis positions //uint8_t broadcast_mac[ESP_NOW_ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Broadcast MAC address //// uint8_t receiver_mac[ESP_NOW_ETH_ALEN] = {0xE4, 0xB0, 0x63, 0x17, 0x9E, 0x45}; // MAC address of Robot //uint8_t receiver_mac[ESP_NOW_ETH_ALEN] = {0x9c, 0x9e, 0x6e, 0x14, 0xb5, 0x54}; // MAC address of Breadboard #2 //uint8_t transmitter_mac[ESP_NOW_ETH_ALEN] = {0x34, 0xB7, 0xDA, 0xF9, 0x33, 0x8D}; // MAC address of Remote Control esp_err_t joystick_adc_init(void) { adc_oneshot_unit_init_cfg_t adc_init_config_xy = { .unit_id = ADC_UNIT_1, .ulp_mode = ADC_ULP_MODE_DISABLE, }; ESP_ERROR_CHECK(adc_oneshot_new_unit(&adc_init_config_xy, &adc_xy_handle)); adc_oneshot_chan_cfg_t config_x = { .bitwidth = SOC_ADC_DIGI_MAX_BITWIDTH, .atten = ADC_ATTEN_DB_12, }; adc_oneshot_chan_cfg_t config_y = { .bitwidth = SOC_ADC_DIGI_MAX_BITWIDTH, .atten = ADC_ATTEN_DB_12, }; ESP_ERROR_CHECK(adc_oneshot_config_channel(adc_xy_handle, ADC_CHANNEL_0, &config_x)); ESP_ERROR_CHECK(adc_oneshot_config_channel(adc_xy_handle, ADC_CHANNEL_1, &config_y)); return ESP_OK; } void joystick_show_raw_xy() { ESP_ERROR_CHECK(adc_oneshot_read(adc_xy_handle, ADC_CHANNEL_0, &x)); ESP_ERROR_CHECK(adc_oneshot_read(adc_xy_handle, ADC_CHANNEL_1, &y)); ESP_LOGI("(x,y)", "( %d, %d )", x, y); } void get_joystick_xy(int *x_axis, int *y_axis) { ESP_ERROR_CHECK(adc_oneshot_read(adc_xy_handle, ADC_CHANNEL_0, x_axis)); ESP_ERROR_CHECK(adc_oneshot_read(adc_xy_handle, ADC_CHANNEL_1, y_axis)); } // Function to delete peer (i.e. when communication error occurs) void deletePeer (void) { uint8_t delStatus = esp_now_del_peer(receiver_mac); if (delStatus != 0) { ESP_LOGE("ESP-NOW", "Could not delete peer"); } } void sendData (void) { buffer.crc = 0; buffer.x_axis = 240; buffer.y_axis = 256; buffer.nav_bttn = 0; buffer.led = 0; buffer.motor1_rpm_pwm = 0; buffer.motor2_rpm_pwm = 0; buffer.motor3_rpm_pwm = 0; buffer.motor4_rpm_pwm = 0; get_joystick_xy(&x, &y); //ESP_LOGI("(x, y)", "[ %d, %d ]", x, y); buffer.x_axis = x; buffer.y_axis = y; // Display brief summary of data being sent. ESP_LOGI(JTAG, "Joystick (x,y) position ( %d, %d )", buffer.x_axis, buffer.y_axis); ESP_LOGI(JTAG, "pwm 1, pwm 2 [ 0x%04X, 0x%04X ]", (uint8_t)buffer.motor1_rpm_pwm, (uint8_t)buffer.motor2_rpm_pwm); ESP_LOGI(JTAG, "pwm 3, pwm 4 [ 0x%04X, 0x%04X ]", (uint8_t)buffer.motor3_rpm_pwm, (uint8_t)buffer.motor4_rpm_pwm); // Call ESP-NOW function to send data (MAC address of receiver, pointer to the memory holding data & data length) uint8_t result = esp_now_send((uint8_t*)receiver_mac, (uint8_t *)&buffer, sizeof(buffer)); // If status is NOT OK, display error message and error code (in hexadecimal). if (result != 0) { ESP_LOGE("sendData()", "Error sending data! Error code: 0x%04X", result); ESP_LOGE("sendData()", "esp_now_send() failed: %s", esp_err_to_name(result)); ESP_LOGE("sendData()", "Ensure that receiver is powered-on."); ESP_LOGE("sendData()", "Ensure that received MAC is: %02X:%02X:%02X:%02X:%02X:%02X", receiver_mac[0], receiver_mac[1], receiver_mac[2], receiver_mac[3], receiver_mac[4], receiver_mac[5]); deletePeer(); } } void joystick_task(void *arg) { while (true) { joystick_show_raw_xy(); vTaskDelay (1000 / portTICK_PERIOD_MS); } } void statusDataSend(const uint8_t *mac_addr, esp_now_send_status_t status) { if (status == ESP_NOW_SEND_SUCCESS) { ESP_LOGI(JTAG, "Data sent successfully to: %02X:%02X:%02X:%02X:%02X:%02X", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); } else { ESP_LOGE(JTAG, "Error sending data to: %02X:%02X:%02X:%02X:%02X:%02X", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); ESP_LOGE(JTAG, "Error sending data. Error code: 0x%04X", status); ESP_LOGE(JTAG, "esp_now_send() failed: %s", esp_err_to_name(status)); ESP_LOGE(JTAG, "Ensure that receiver is powered-on and MAC is correct."); deletePeer(); } } /* WiFi should start before using ESPNOW */ void wifi_init() { ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA));//ESPNOW_WIFI_MODE)); ESP_ERROR_CHECK( esp_wifi_start()); ESP_ERROR_CHECK( esp_wifi_set_channel(CONFIG_ESPNOW_CHANNEL, WIFI_SECOND_CHAN_NONE)); #if CONFIG_ESPNOW_ENABLE_LONG_RANGE ESP_ERROR_CHECK( esp_wifi_set_protocol(ESPNOW_WIFI_IF, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR) ); #endif } void rc_send_data_task() { while (true) { if (esp_now_is_peer_exist((uint8_t*)receiver_mac)) { sendData(); } vTaskDelay (1000 / portTICK_PERIOD_MS); } } void transmission_init() { esp_err_t espnow_ret = esp_now_init(); if (espnow_ret != ESP_OK) { ESP_LOGE(TAG, "esp_now_init() failed: %s", esp_err_to_name(espnow_ret)); return; } ESP_LOGI(TAG, "ESPNOW initialized successfully"); esp_now_register_send_cb(statusDataSend); // Set ESP-NOW receiver device configuration values memcpy(devices.peer_addr, receiver_mac, 6); devices.channel = 1; devices.encrypt = false; esp_now_add_peer(&devices); }