I am using ESP8266 with STM32F103. The ESP receives the AT-command correctly and executes it, and I can receive the echo characters, but when it comes to the ESP response I can't receive anything.
Here is a pic to demonstrate the issue:
https://drive.google.com/file/d/19Of8ENNDDB0YAV5H5HuamcWF_OwV8JSj/view?usp=sharing
For instance: I send ATE0 to stop the echo, the ESP executes the command and there is no echo anymore, but I can't receive "OK" or "WIFI CONNECTED" or any other response.
I have tried putty and it worked without any problems in sending or receiving, so the ESP is fine.
I am using 115200 Baud rate, and this is my code:
main:
void main(void)
{
/* Init RCC */
RCC_voidInitSysClock();
/* Enable Clock For GPIOA & UART1 */
RCC_voidEnableClock(RCC_APB2,GPIOA_BUS);
RCC_voidEnableClock(RCC_APB2,14);
/* Set TX and Rx Directions */
MGPIO_voidSetPinDirection(GPIOA, PIN9 ,OUTPUT_SPEED_2MHZ_AFPP); /* TX */
MGPIO_voidSetPinDirection(GPIOA, PIN10 ,INPUT_FLOATING); /* RX */
/* Set Direction For Pin 0 To power Led */
MGPIO_voidSetPinDirection(GPIOA, PIN0 ,OUTPUT_SPEED_10MHZ_PP);
/* Enable UART1 Interrupt */
MNVIC_voidEnableInterrupt(USART1_ID);
/* Init UART1 */
MUART_voidInit();
/* Init ESP */
HESP_voidInit();
/* Connect To WIFI Network */
HESP_voidConnecttoWifi("Androidap","111112222");
//HESP_voidConnectToServerTCP("162.253.155.226","80");
//HESP_u8ReceiveResponse("Abdullaharm.freevar.com/status.txt","47");
while(1)
{
}
}
Implementation of ESP_init and connect to WIFI functions:
void HESP_voidInit(void)
{
//MUART_voidTransmitSynch("AT\r\n");
/* Stop Echo */
MUART_voidTransmitSynch("ATE0\r\n");
/* Set Station Mode */
MUART_voidTransmitSynch("AT+CWMODE=1\r\n");
MSYSTICK_voidSetBusyWait(1000);//microseconds
}
void HESP_voidConnecttoWifi(uint8* Copy_u8SSID , uint8* Copy_u8Pass)
{
/* Connect to WIFI network */
MUART_voidTransmitSynch("AT+CWJAP_CUR=\"");
MUART_voidTransmitSynch(Copy_u8SSID);
MUART_voidTransmitSynch("\",\"");
MUART_voidTransmitSynch(Copy_u8Pass);
MUART_voidTransmitSynch("\"\r\n");
}
Implementaion of UART_TransmitSynch:
void MUART_voidTransmitSynch(uint8 arr[])
{
uint8 i=0;
while(arr[i] != '\0')
{
UART1 -> DR = arr[i];
/* wait till transmission is complete */
while (!(UART1->SR & (1<<6)));
i++;
MSYSTICK_voidSetBusyWait(2000); //microseconds
}
}
I am using interrupt to receive from the ESP and this is the code inside ISR:
void USART1_IRQHandler(void)
{
if(GET_BIT(UART1 -> SR , 5))
{
static uint8 Data_Counter=0;
if(UART1 -> DR !='\0')
{
Data_Received_int[Data_Counter]=UART1 -> DR;
Data_Counter++;
}
else
{
Data_Counter=0;
}
CLR_BIT(UART1 -> SR , 5);
}
//UART_CallBackPtr();
}
Related
I am using code derived from Rui Santos https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
I am using ESP NOW to send readings from an ESP32 sender to an ESP32 receiver then using the ESP32 receiver to send an html message to a ESP32 web server. Per Rui's instructions I need to start WiFi with WIFI_AP_STA to allow both wifi connection methods.
The sender and receiver code is below.
If I run the code as is, i.e. the receiver setup as WIFI_AP_STA but with the WiFi.begin line commented out, I get a sender status of:
Send success, and a receive status of:Receive status. SO there is no problem sending an ESP NOW message from the sender to the receiver (also works with WIFI_STA).
If I use WIFI_AP_STA and uncomment the line in the receiver "WiFi.begin(SSIS, PASSWORD)" so that I can send a message to the ESP32 web server, I get a send status of:Send fail, and a receive status of:Receive status with failed send. The send fails but the receive is still successful. Same fail if I use WIFI_AP. It seems that in WIFI_AP_STA mode with a WiFi.begin, the receiver sends an incorrect status back to the sender.
In summary, on the receiver, using wifi mode WIFI_AP_STA without a WiFi.begin, works for sending an ESP NOW message from sender to receiver, as it should.
Using wifi mode WIFI_AP_STA and WiFi.begin on the receiver, the sender fails when sending an ESP NOW message. When I implement the web code the web html message send works. However the issue can be reproduced using the simplified code below.
Using WiFi#2.0.0.
I've run out of ideas, is anyone able to point me at further investigation areas?
My sender code is:
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
// Rui Santos https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
uint8_t broadcastAddress[] = {0x24, 0x6F, 0x28, 0xAA, 0x84, 0x10};
typedef struct struct_message
{
char ESP32NowText[33];
} struct_message;
struct_message ESP32NowMessage;
//
String text = "AAA000010000200003000040000500006";
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK)
{
Serial.println("Failed to add peer");
return;
}
}
void loop()
{
strncpy(ESP32NowMessage.ESP32NowText, text.c_str(), text.length());
Serial.println("Msg to send:" + String(ESP32NowMessage.ESP32NowText));
Serial.println("Snd Len:" + String(sizeof(ESP32NowMessage)));
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&ESP32NowMessage, sizeof(ESP32NowMessage));
if (result == ESP_OK)
{
Serial.println("Sent with success");
}
else
{
Serial.println("Error sending the data");
}
delay(2000);
}
My receiver code is:
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
// Rui Santos https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
typedef struct struct_message
{
char ESP32NowValues[33];
} struct_message;
struct_message ESP32NowMessage;
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len)
{
memcpy(&ESP32NowMessage, incomingData, sizeof(ESP32NowMessage));
Serial.println("Bytes received: " + String(len));
Serial.println("Values:" + String(ESP32NowMessage.ESP32NowValues));
Serial.println("---------------------------------------");
}
const char WiFiSSID[] = "SSID";
const char WiFiPassword[] = "PASSWORD";
//
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_AP_STA);
// WiFi.begin(WiFiSSID, WiFiPassword);
// Init ESP-NOW
if (esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
void loop()
{
}
I started to test the ESP8266 module, i wrote in the serial port this commands: AT, AT+RST, AT+CWMODE=1(station mode), AT+CWLAP, AT+CWJAP="My network name","password", AT+CIPMUX=1, AT+CIPSERVER=1,80, AT+CIPSEND=0,"numer of char of my string", "MyMessage", AT+CIPCLOSE=0 and it work, its sends the message to my phone.
Now I try to do some function that sends automatically those commands, but when i get to the sending message part it gives me an error.
I post my code below:
#include <SoftwareSerial.h>
SoftwareSerial ESPserial(9, 10); // RX | TX
void setup()
{
Serial.begin(9600); // communication with the host computer
// Start the software serial for communication with the ESP8266
ESPserial.begin(9600);
delay(1000);
Serial.println("");
Serial.println("Remember to to set Both NL & CR in the serial monitor.");
Serial.println("Ready");
Serial.println("");
trimiteDate("AT+IPR=9600",1000);
trimiteDate("AT",1000);
trimiteDate("AT+RST",1000);
trimiteDate("AT+CWMODE=1",1000);
trimiteDate("AT+CWLAP",1000);
trimiteDate("AT+CWJAP=\"DIGI_d61430\",\"ddcc29eb\"",1000);
trimiteDate("AT+CIFSR",1000);
trimiteDate("AT+CIPMUX=1",1000);
trimiteDate("AT+CIPSERVER=1,80",1000);
scrie("Sir de caractere",1000);
}
void loop()
{
// listen for communication from the ESP8266 and then write it to the serial monitor
if ( ESPserial.available() ) { Serial.write( ESPserial.read() ); }
// listen for user input and send it to the ESP8266
if ( Serial.available() ) { ESPserial.write( Serial.read() ); }
}
void trimiteDate(String comanda, const int timp ){
ESPserial.println(comanda);
while ( ESPserial.available() ) { Serial.write( ESPserial.read() ); }
while ( Serial.available() ) { ESPserial.write( Serial.read() );}
delay(timp);
}
void scrie(String sir, const int timp){
int lungimeSir = sir.length();
String startTransmisie = "AT+CIPSEND=1,";
String stopTransmisie = "AT+CIPCLOSE=0";
String sirDate = startTransmisie + lungimeSir;
trimiteDate(sirDate,1000);
ESPserial.println(sir);
trimiteDate(stopTransmisie,1000);
delay(timp);
}
Using CubeMX, TrueStudio, an STM32F767ZI, and HAL, I am developing software to access a USB Flash drive using FatFS though the USB host port.
The board has a host and device USB connector attached to the MCU.
Within CubeMX, I configured FreeRTOS, USB Host MSC, and FatFS.
This works, I can see these different states when plugging and unplugging the flash drive:
--- Plugging in USB flash drive ---
HOST_USER_CONNECTION
HOST_USER_CONNECTION
HOST_DEV_ATTACHED
phost->device.speed: 1
HOST_ENUMERATION
HOST_SET_CONFIGURATION
HOST_SET_WAKEUP_FEATURE
HOST_CHECK_CLASS
USBH_MSC_InterfaceInit
HOST_CLASS_REQUEST
USBH_MSC_ClassRequest
HOST_CLASS
USBH_MSC_Process
processId: 3, Appli_state 1
USBH_MSC_GetLUNInfo
info.capacity.block_nbr : 623395
info.capacity.block_size: 512
capacity : 3116 MB
HOST_USER_CLASS_ACTIVE
FATFS_LinkDriver Failed
USBDISKPath:
processId: 2, Appli_state 2
USBH_MSC_GetLUNInfo
info.capacity.block_nbr : 62333951
info.capacity.block_size: 512
capacity : 31166 MB
--- Unplugging USB flash drive ---
HOST_USER_DISCONNECTION
HOST_DEV_DISCONNECTED
USBH_MSC_InterfaceDeInit
processId: 5, Appli_state 3
USBH_MSC_GetLUNInfo
info.capacity.block_nbr : 62333951
info.capacity.block_size: 512
capacity : 31166 MB
So, after MX_USB_HOST_Init(); was called in freertos.c all the above happened.
FATFS_LinkDriver() is called from MX_FATFS_Init().
But the functions in usbh_diskio.c are not called, so something went wrong there.
The pieces of code I'm looking at are these:
freertos.c, where MX_USB_HOST_Init() is called, after this the MSC is registered.
/* StartDefaultTask function */
void StartDefaultTask(void const * argument)
{
/* init code for FATFS */
MX_FATFS_Init();
/* init code for LWIP */
MX_LWIP_Init();
/* init code for USB_HOST */
MX_USB_HOST_Init();
/* init code for USB_DEVICE */
MX_USB_DEVICE_Init();
/* init code for LIBJPEG */
MX_LIBJPEG_Init();
/* USER CODE BEGIN StartDefaultTask */
MSC_LUNTypeDef info;
uint8_t lun = 0;
uint16_t val = 0;
/* Infinite loop */
for(;;)
{
/* USB Host Background task */
// USBH_Process(&hUsbHostFS);
val++;
if (val >= 1000)
{
if (processIdOld != processId)
{
printf("processId: %d, Appli_state %d\n", processId, Appli_state);
processIdOld = processId;
USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info);
uint32_t cap = info.capacity.block_nbr / 2000;
printf("info.capacity.block_nbr : %ld\n", info.capacity.block_nbr);
printf("info.capacity.block_size: %d\n", info.capacity.block_size);
printf("capacity : %d MB\n", cap);
}
// printf("1");
// fflush(stdout);
// HAL_GPIO_TogglePin(PIO10_LED_RS_ERR_GPIO_Port, PIO10_LED_RS_ERR_Pin);
val = 0;
}
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
usb_host.c, where USB is initialized, and I can see USBH_UserProcess is called when I plug/unplug the USB flash drive.
void MX_USB_HOST_Init(void)
{
/* USER CODE BEGIN USB_HOST_Init_PreTreatment */
/* USER CODE END USB_HOST_Init_PreTreatment */
/* Init host Library, add supported class and start the library. */
USBH_Init(&hUsbHostFS, USBH_UserProcess, HOST_FS);
USBH_RegisterClass(&hUsbHostFS, USBH_AUDIO_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_CDC_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_MSC_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_HID_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_MTP_CLASS);
USBH_Start(&hUsbHostFS);
/* USER CODE BEGIN USB_HOST_Init_PostTreatment */
/* USER CODE END USB_HOST_Init_PostTreatment */
}
/*
* user callback definition
*/
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{
/* USER CODE BEGIN CALL_BACK_1 */
switch(id)
{
case HOST_USER_SELECT_CONFIGURATION:
printf("HOST_USER_SELECT_CONFIGURATION\n");
break;
case HOST_USER_DISCONNECTION:
printf("HOST_USER_DISCONNECTION\n");
Appli_state = APPLICATION_DISCONNECT;
break;
case HOST_USER_CLASS_ACTIVE:
printf("HOST_USER_CLASS_ACTIVE\n");
Appli_state = APPLICATION_READY;
break;
case HOST_USER_CONNECTION:
printf("HOST_USER_CONNECTION\n");
Appli_state = APPLICATION_START;
break;
default:
break;
}
/* USER CODE END CALL_BACK_1 */
}
The above part works fine, sofar.
Except the linking of the usbh driver.
Has anybody used this or know good working examples?
I have searched for solution for this issue for quite a long time with no luck.
I would like NodeMCU to look for an open wifi network and connect to it. As long as the connection is available use that connection - and when the connection drops start looking for a new open network.
I live in Finland and we have free open WiFi almost on every corner. I am planning on creating something wearable/mobile that would use WiFi when available.
I am also only starting on programming, basics in C and using the Arduino IDE so no Lua language experience here.
I understand that WiFi.scanNetworks() can distinguish a secure from an unsecured SSID, but I haven't found out how I could use that to my advantage in Arduino IDE.
You can scan for networks also in STA mode.
The method you need is WiFi.encryptionType() after WiFi.scanNetworks() to determine whether a network encrypted or not.
I am sharing a sketch with you that I was working on for a similar project previously.
Sketch searches for WiFi networks, sorts them in order to RSSI, and performs connection on non-encrypted one with highest strength.
Here it is, good luck:
#include <ESP8266WiFi.h>
/* Serial Baud Rate */
#define SERIAL_BAUD 9600
/* Delay paramter for connection. */
#define WIFI_DELAY 500
/* Max SSID octets. */
#define MAX_SSID_LEN 32
/* Wait this much until device gets IP. */
#define MAX_CONNECT_TIME 30000
/* SSID that to be stored to connect. */
char ssid[MAX_SSID_LEN] = "";
/* Scan available networks and sort them in order to their signal strength. */
void scanAndSort() {
memset(ssid, 0, MAX_SSID_LEN);
int n = WiFi.scanNetworks();
Serial.println("Scan done!");
if (n == 0) {
Serial.println("No networks found!");
} else {
Serial.print(n);
Serial.println(" networks found.");
int indices[n];
for (int i = 0; i < n; i++) {
indices[i] = i;
}
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) {
std::swap(indices[i], indices[j]);
}
}
}
for (int i = 0; i < n; ++i) {
Serial.print(WiFi.SSID(indices[i]));
Serial.print(" ");
Serial.print(WiFi.RSSI(indices[i]));
Serial.print(" ");
Serial.print(WiFi.encryptionType(indices[i]));
Serial.println();
if(WiFi.encryptionType(indices[i]) == ENC_TYPE_NONE) {
Serial.println("Found non-encrypted network. Store it and exit to connect.");
memset(ssid, 0, MAX_SSID_LEN);
strncpy(ssid, WiFi.SSID(indices[i]).c_str(), MAX_SSID_LEN);
break;
}
}
}
}
void setup() {
Serial.begin(SERIAL_BAUD);
Serial.println("Started.");
}
void loop() {
if(WiFi.status() != WL_CONNECTED) {
/* Clear previous modes. */
WiFi.softAPdisconnect();
WiFi.disconnect();
WiFi.mode(WIFI_STA);
delay(WIFI_DELAY);
/* Scan for networks to find open guy. */
scanAndSort();
delay(WIFI_DELAY);
/* Global ssid param need to be filled to connect. */
if(strlen(ssid) > 0) {
Serial.print("Going to connect for : ");
Serial.println(ssid);
/* No pass for WiFi. We are looking for non-encrypteds. */
WiFi.begin(ssid);
unsigned short try_cnt = 0;
/* Wait until WiFi connection but do not exceed MAX_CONNECT_TIME */
while (WiFi.status() != WL_CONNECTED && try_cnt < MAX_CONNECT_TIME / WIFI_DELAY) {
delay(WIFI_DELAY);
Serial.print(".");
try_cnt++;
}
if(WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("Cannot established connection on given time.");
}
} else {
Serial.println("No non-encrypted WiFi found.");
}
}
}
I am trying to make a wireless light control device (on/off/dimming) using an Arduino, an Android app, and a router.
I am setting the Arduino to a static IP 192.168.1.2 using the router. I am sending strings ("1"-off, "2"-decrease brightness, "3"-increase brightness, "4"-on) from the Android app to the IP address 192.168.1.2. I have connected the Arduino to the Internet using the Arduino Wi-Fi shield and set up the WifiServer using the following code:
char ssid[] = "NAME"; // Your network SSID (name)
char pass[] = "PASS"; // Your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // Your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
WiFiServer server(23);
boolean alreadyConnected = false; // Whether or not the client was connected previously.
void setup() {
// Start serial port:
Serial.begin(9600);
// Attempt to connect to Wi-Fi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
// Wait 10 seconds for connection:
delay(10000);
}
// Start the server:
server.begin();
// You're connected now, so print out the status:
printWifiStatus();
}
The main problem I am having is how to accept and print out the strings from the Android device. The current code I have to do this is:
// Listen for incoming clients
WiFiClient client = server.available();
if (client) {
// An HTTP request ends with a blank line
boolean newLine = true;
String line = "";
while (client.connected() && client.available()) {
char c = client.read();
Serial.print(c);
// If you've gotten to the end of the line (received a newline
// character) and the line is blank, the HTTP request has ended,
// so you can send a reply.
if (c == '\n' && newLine) {
// Send a standard HTTP response header
//client.println("HTTP/1.1 200 OK");
//client.println("Content-Type: text/html");
//client.println();
}
if (c == '\n') {
// You're starting a new line
newLine = true;
Serial.println(line);
line = "";
}
else if (c != '\r') {
// You've gotten a character on the current line
newLine = false;
line += c;
}
}
Serial.println(line);
// Give the web browser time to receive the data
delay(1);
// Close the connection:
//client.stop();
}
}
I am basing this code off of the blog post Android Arduino Switch with a TinyWebDB hack, but this code is for an Ethernet shield. The Android app was made using the MIT App Inventor, which is similar to the one found the blog post.
TLDR, how can I get the strings using the Arduino Wi-Fi shield?
You can read the characters into a full string instead of reading each individual character into the serial monitor as in your example above.
In your example, this bit of code would read each character from the client TCP session and print it to the serial monitor, thus displaying the HTTP requests in the serial console.
char c = client.read();
Serial.print(c);
Try something like this instead. Declare a string named "readString" before your setup() function in the Arduino sketch like this:
String readString;
void setup() {
//setup code
}
void loop() {
// Try this when you're reading inside the while client.connected loop instead of the above:
if (readString.length() < 100) {
readString += c;
Serial.print(c);
}
Here is a working example of the loop():
void loop() {
// Listen for incoming clients
WiFiClient client = server.available();
if (client) {
Serial.println("new client");
// An HTTP request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
//Serial.write(c);
// If you've gotten to the end of the line (received a newline
// character) and the line is blank, the HTTP request has ended,
// so you can send a reply.
if (readString.length() < 100) {
readString += c;
Serial.print(c);
}
if (c == '\n' && currentLineIsBlank) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connnection: close");
client.println();
client.println("<!DOCTYPE HTML>");
//send the HTML stuff
client.println("<html><head><title>Admin Web</title><style type=\"text/css\">");
client.println("body { font-family: sans-serif }");
client.println("h1 { font-size: 14pt; }");
client.println("p { font-size: 10pt; }");
client.println("a { color: #2020FF; }");
client.println("</style>");
client.println("</head><body text=\"#A0A0A0\" bgcolor=\"#080808\">");
client.println("<h1>Arduino Control Panel</h1><br/>");
client.println("<form method=\"link\" action=\"/unlockdoor\"><input type=\"submit\" value=\"Unlock Door!\"></form>");
client.println("<br/>");
client.println("</body></html>");
break;
}
if (c == '\n') {
// You're starting a new line.
currentLineIsBlank = true;
}
else if (c != '\r') {
// You've gotten a character on the current line.
currentLineIsBlank = false;
}
}
}
// Give the web browser time to receive the data.
delay(1);
// Close the connection:
client.stop();
Serial.println("client disonnected");
if (readString.indexOf("/unlockdoor") > 0)
{
unlockdoor();
Serial.println("Unlocked the door!");
}
readString = "";
}