Code: Select all
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include <stdio.h>
#include "esp_sleep.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "driver/rtc_io.h"
#include "esp32/ulp.h"
#include "ulp_main.h"
#include "driver/mcpwm.h"
#include "driver/ledc.h"
#include <errno.h>
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
#define AP_SSID "ThePartyHouse" // for soft-AP, set variable "AP" to "1" below
#define OUT_GPIO 5 // this is the pin toggled
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const int CONNECTED_BIT = BIT0;
/* Constants that aren't configurable in menuconfig */
#define PORT "7777"
#define beServer 1 // set to 1 if you want the ESP to listen for connections to PORT, otherwise it will connect to SERVER address below
#define AP 0 // set to 1 if you want SoftAP, otherwise it will connect to the AP specified in sdkconfig (menuconfig)
#if AP
#define SERVER "192.168.4.2" //softAP mode. this is the default IP of the first connected station (change if not the case)
#else
#define SERVER "192.168.0.52" //station mode. this is the IP address of the echo server (usually a desktop)
#endif
// 2028 is currently max usable size that works (but is risky, since it is 4 rows over compiler limit)
#define ulp_rows 2000 // must match rows defined in assembly file
extern const uint8_t bin_start [] asm ("_binary_ulp_main_bin_start");
extern const uint8_t bin_end [] asm ("_binary_ulp_main_bin_end");
static const char *TAG = ">";
static const char *REQUEST = "message from server1";
int s, r, sock;
char recv_buf[64];
struct sockaddr_in clientAddress; struct sockaddr_in serverAddress;
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_AP_START:
ESP_LOGI(TAG, "Soft-AP started" );
//esp_wifi_connect();
break;
case SYSTEM_EVENT_AP_STACONNECTED:
ESP_LOGI(TAG, "station connected to this soft-AP: %s", AP_SSID );
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
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) );
if (AP != 0)
{
ESP_LOGI(TAG, "Setting WiFi mode to Soft-AP" );
wifi_config_t ap_config = {
.ap = {
.ssid = AP_SSID,
.channel = 0,
.authmode = WIFI_AUTH_OPEN,
.ssid_hidden = 0,
.max_connection = 2,
.beacon_interval = 100
}
};
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) );
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_AP, &ap_config));
}
else
{
ESP_LOGI(TAG, "Setting WiFi mode to station" );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...",wifi_config.sta.ssid );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
}
ESP_ERROR_CHECK( esp_wifi_start() );
}
static void rxtxpacket_client(void *pvParameters)
{
while (1)
{
if (write(s, REQUEST, strlen(REQUEST)) < 0) {
ESP_LOGE(TAG, "... socket send failed");
close(s);
vTaskDelay(4000 / portTICK_RATE_MS);
continue;
}
ESP_LOGI(TAG, "... socket send success");
/* Read response */
do {
bzero(recv_buf, sizeof(recv_buf));
r = read(s, recv_buf, sizeof(recv_buf)-1);
for(int i = 0; i < r; i++) {
putchar(recv_buf[i]);
}
} while(r == (sizeof(recv_buf)-1));
ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d\r\n", r, errno);
}
}
static void rxtxpacket_server(void *pvParameters)
{
ESP_LOGI(TAG, "Server listening on port %s...", PORT);
while (1)
{
// Listen for a new client connection.
socklen_t clientAddressLength = sizeof(clientAddress);
int clientSock = accept(sock, (struct sockaddr *)&clientAddress, &clientAddressLength);
if (clientSock < 0)
{
ESP_LOGE(TAG, "accept: %d %s", clientSock, strerror(errno));
goto END;
}
ESP_LOGE(TAG, "accept: %d %s", clientSock, strerror(errno));
// We now have a new client ...
int total = 10*1024;
int sizeUsed = 0;
char *data = malloc(total);
ESP_LOGI(TAG, "client accepted %d...", clientSock);
// Loop reading data.
while(1)
{
ssize_t sizeRead = recv(clientSock, data + sizeUsed, total-sizeUsed, 0);
if (sizeRead < 0)
{
ESP_LOGE(TAG, "recv: %d %s", sizeRead, strerror(errno));
goto END;
}
if (sizeRead == 0)
{
break;
}
sizeUsed += sizeRead;
}
// Finished reading data.
ESP_LOGE(TAG, "Data read (size: %d) was: %.*s", sizeUsed, sizeUsed, data);
free(data);
close(clientSock);
}
END:
vTaskDelete(NULL);
}
static void startClient(void)
{
const struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
};
struct addrinfo *res;
struct in_addr *addr;
/* Wait for the callback to set the CONNECTED_BIT in the
event group.
*/
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
false, true, portMAX_DELAY);
if (!AP)
{
ESP_LOGI(TAG, "Connected to AP");
}
int err = getaddrinfo(SERVER, PORT, &hints, &res); // changed PORT to "7777"
if(err != 0 || res == NULL) {
ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res);
vTaskDelay(1000 / portTICK_RATE_MS);
//continue;
}
/* Code to print the resolved IP.
Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */
addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr));
s = socket(res->ai_family, res->ai_socktype, 0);
if(s < 0) {
ESP_LOGE(TAG, "... Failed to allocate socket.");
freeaddrinfo(res);
vTaskDelay(1000 / portTICK_RATE_MS);
//continue;
}
ESP_LOGI(TAG, "... allocated socket\r\n");
if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
ESP_LOGE(TAG, "... socket connect failed errno=%d. make sure echo server is listening on port 7777 and restart make monitor.", errno);
close(s);
freeaddrinfo(res);
vTaskDelay(4000 / portTICK_RATE_MS);
//continue;
}
else
{
ESP_LOGI(TAG, "... connected");
freeaddrinfo(res);
}
}
static void startServer(void)
{
/* Wait for the callback to set the CONNECTED_BIT in the
event group.
*/
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
false, true, portMAX_DELAY);
ESP_LOGI(TAG, "Initializing server to listen for connections...");
// Create a socket that we will listen upon.
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0)
{
ESP_LOGE(TAG, "socket: %d %s", sock, strerror(errno));
goto END;
}
ESP_LOGE(TAG, "socket: %d %s", sock, strerror(errno));
// Bind our server socket to a port.
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(PORT);
int rc = bind(sock, (struct sockaddr *)&serverAddress, sizeof(serverAddress));
if (rc < 0)
{
ESP_LOGE(TAG, "bind: %d %s", rc, strerror(errno));
goto END;
}
ESP_LOGE(TAG, "bind: %d %s", rc, strerror(errno));
// Flag the socket as listening for new connections.
rc = listen(sock, 5);
if (rc < 0)
{
ESP_LOGE(TAG, "listen: %d %s", rc, strerror(errno));
goto END;
}
ESP_LOGE(TAG, "listen: %d %s", rc, strerror(errno));
END:
//ESP_LOGI(TAG, "there was an error, skipped the rest of the port setup: %s", strerror(errno));
// vTaskDelete(NULL);
return;
}
void toggle_pin(void *pvParameter)
{
gpio_pad_select_gpio(OUT_GPIO);
gpio_set_direction(OUT_GPIO, GPIO_MODE_OUTPUT);
while(1) {
gpio_set_level(OUT_GPIO, 1);
vTaskDelay(8 / portTICK_RATE_MS); // 9ms or less delay on either side of pin change always produces 3.3v, 64KHz square wave on scope. but 10ms drops to 50hz. why non-linear?
gpio_set_level(OUT_GPIO, 0);
vTaskDelay(8 / portTICK_RATE_MS);
}
}
static void PWM_out (void)
{
int i, shift = 0;
// IO pins used for PWM outputs
const char m_io [12] = {15, 2, 0, 4, 16, 17, 5, 18, 19, 21, 22, 23};
const char l_io [8] = {13, 12, 14, 27, 26, 25, 33, 32};
// configure motor PWMs
mcpwm_config_t config = {20000, 0, 0, MCPWM_DUTY_MODE_0, MCPWM_UP_COUNTER};
for (i = 0; i < 12; ++i)
{
mcpwm_gpio_init (i / 6, i % 6, m_io [i]);
if (i & 1)
mcpwm_init (i / 6, (i / 2) % 3, &config);
mcpwm_set_duty_type (i / 6, (i / 2) % 3, i & 1, MCPWM_DUTY_MODE_0);
}
// configure LED PWMs
ledc_channel_config_t channel = {0, LEDC_HIGH_SPEED_MODE, 0, LEDC_INTR_DISABLE, LEDC_TIMER_0, 0};
for (i = 0; i < 8; ++i)
{
channel.channel = i;
channel.gpio_num = l_io [channel.channel];
ledc_channel_config (&channel);
}
ledc_timer_config_t timer = {LEDC_HIGH_SPEED_MODE, {LEDC_TIMER_10_BIT, 0}, LEDC_TIMER_0, 20000};
ledc_timer_config (&timer);
// Output continuously increasing, staggered duty cycle waves on all 20 channels
while (1)
{
for (i = 0; i < 12; ++i)
mcpwm_set_duty (i / 6, (i / 2) % 3, i & 1, ((shift + 52 * i) % 1024) / 10.24);
for (i = 0; i < 8; ++i)
{
ledc_set_duty (LEDC_HIGH_SPEED_MODE, i, (shift + 52 * (i + 12)) % 1024);
ledc_update_duty (LEDC_HIGH_SPEED_MODE, i);
}
shift = (shift + 1) % 1024;
vTaskDelay (100 / portTICK_RATE_MS);
}
}
void app_main()
{
nvs_flash_init();
initialise_wifi();
vTaskDelay(2000 / portTICK_RATE_MS);
if (beServer == 1)
{
startServer();
xTaskCreate(&rxtxpacket_server, "rxtxpacket_server", 2048, NULL, 5, NULL);
}
else
{
startClient();
xTaskCreate(&rxtxpacket_client, "rxtxpacket_client", 2048, NULL, 5, NULL);
}
//xTaskCreate (PWM_out, "PWM output", 4096, NULL, 5, NULL);
//xTaskCreate(&toggle_pin, "toggle_pin", 512, NULL, 10, NULL);
}
0x4011a218: tcpip_adapter_dhcpc_start_api at C:/msys32/home/Peter/esp/esp-idf/components/tcpip_adapter/tcpip_adapter_l
D (3080) tcpip_adapter: if0 start ip lost tmr: no need start because netif=0x3ffc57b4 interval=120 ip=0
0x4011a218: tcpip_adapter_dhcpc_start_api at C:/msys32/home/Peter/esp/esp-idf/components/tcpip_adapter/tcpip_adapter_l
D (3750) event: SYSTEM_EVENT_STA_GOT_IP, ip:192.168.0.34, mask:255.255.255.0, gw:192.168.0.1
I (3770) >: Initializing server to listen for connections...
I (3780) >: Server listening on port 7777...