Arduino: How to beginTransmission inside onReceive - arduino-uno

I have 3 Arduinos that are connected via I2C.
My goal is to send a data from slave1 to master and then after that send that data from master to slave 2.
My problem is that, whenever I use beginTransmission, it does not send the data from master to slave 2.
Here is the example of my code:
//Wire Master
#include<Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
lcd.begin(16, 2);
lcd.print("Ref Door Status");
Wire.begin(1);
Serial.begin(9600);
Wire.onReceive(receivedEvent);
}
void loop() {
/*Wire.requestFrom(9,1);
while(Wire.available()){
c = Wire.read();
if(c=='O'){
lcd.setCursor(0, 1);
lcd.print("OPEN");
}
else if (c == 'C'){
lcd.setCursor(0, 1);
lcd.print("CLOSE");
}
}*/
}
void receivedEvent(int howMany){
while(Wire.available()){
char c = Wire.read();
if(c=='O'){
//openRef();
lcd.setCursor(0, 1);
lcd.print("OPENED");
Wire.beginTransmission(8);
Wire.write('O');
Wire.endTransmission();
}
else if (c == 'C'){
//closeRef();
lcd.setCursor(0, 1);
lcd.print("CLOSED");
}
}
}
I really would appreciate your help.

Related

ESP32 (ESP-IDF) "driver/twai.h" CAN Data Transmission is working but Receive function is not working using CAN/TWAI

I saw a YouTube video with someone who used a similar code, and it was working perfectly for him (YouTube Video: link: https://youtu.be/bxzWuIqfn9Y). He used "driver/can.h" which has been removed from v5.0 of ESP-IDF because CAN and TWAI are the same.
More details:
Issue raised on GitHub: https://github.com/espressif/esp-idf/issues/10757#issue-1582253298
IDF version used: v5.0 and v4.4.4
Operating System used: Windows
IDE used to program and flash code: VS Code IDE
This is my code:
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "stdio.h"
#include "stdlib.h"
#include "driver/twai.h"
void twai_setup_and_install(){
//Initialize configuration structures using macro initializers
twai_general_config_t g_config = {
.mode = TWAI_MODE_NORMAL,
.tx_io = GPIO_NUM_5,
.rx_io = GPIO_NUM_4,
.clkout_io = TWAI_IO_UNUSED,
.bus_off_io = TWAI_IO_UNUSED,
.tx_queue_len = 5,
.rx_queue_len = 5,
.alerts_enabled = TWAI_ALERT_NONE,
.clkout_divider = 0
};
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
// Install TWAI driver
if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
printf("Driver installed\n");
} else {
printf("Failed to install driver\n");
return;
}
// Start TWAI driver
if (twai_start() == ESP_OK) {
printf("Driver started\n");
} else {
printf("Failed to start driver\n");
return;
}
}
void new_message(twai_message_t *message, uint32_t id, uint8_t dlc, uint8_t *data)
{
message->flags = TWAI_MSG_FLAG_NONE;
message->identifier = id;
message->data_length_code = dlc;
for (int i = 0; i < dlc; i++) {
message->data[i] = data[i];
}
printf("Message created\nID: %ld DLC: %d Data:\t", message->identifier, message->data_length_code);
for (int i = 0; i < message->data_length_code; i++) {
printf("%d\t", message->data[i]);
}
printf("\n");
}
void transmit_message(twai_message_t *message)
{
if (twai_transmit(message, pdMS_TO_TICKS(1000)) == ESP_OK) {
printf("Message queued for transmission\n");
} else {
printf("Failed to send message\n");
}
}
void receive_message(twai_message_t *message)
{
if (twai_receive(message, pdMS_TO_TICKS(1000)) == ESP_OK) {
printf("Message received:\n");
printf("ID: %ld DLC: %d Data:\t", message->identifier, message->data_length_code);
for (int i = 0; i < message->data_length_code; i++) {
(message->extd)?printf("Extended ID"):printf("Standard ID");
printf("%d\t", message->data[i]);
}
} else {
printf("Failed to receive message\n");
}
}
void app_main()
{
twai_setup_and_install();
twai_message_t message;
twai_message_t message1;
// Set the data to send
uint8_t data[8] = {rand() % 255, rand() % 255, rand() % 255,
rand() % 255, rand() % 255, rand() % 255, rand() % 255, rand() % 255};
while(true){
// Create a new message
new_message(&message, 0x123, 8, data);
// Transmit the message to a queue
transmit_message(&message);
// Receive the message from the queue
receive_message(&message1);
// Wait for 1 second
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
If anyone can help me as soon as possible, it would be really appreciated.
Sincere Regards.
Steps followed:
I used ESP-IDF v5.0 with VS Code.
I used the documentation to obtain the code for sender and receiver.
I used a tested and functional MCP2515 module as my transceiver for the same.
The Tx is broadcasting perfectly, but the Rx is not working for the above code.
Expected Output:
Message received:
ID: 0x123 DLC: 8 Data: 1 2 3 4 5 6 7 8
In my source code, I have implemented random data bits, so data may vary
Actual Output:
Failed to receive message

Keep ESP32 AutoConnect Captive Portal Always Running

I have an ESP32 that is running in softap mode with AutoConnect. I'm trying to get the captive portal to always be active, even if the client portion is connected to an AP. The current problem is once the ESP32 establishes the client connection with the router or after the initial timeout period, the captive portal goes away and you have to manually enter the IP address of the of the softap in the web browser.
Is there a setting I'm missing that allows this to happen?
//Config.autoRise = true;
Config.immediateStart = true;
Config.portalTimeout = 30 * 1000;
Config.retainPortal = true;
Config.title = "ESP32 AP";
Config.homeUri = "/";
portal.config(Config);
AutoConnectConfig Config;
//Config.bootUri=URI;
Config.homeUri="/_ac";
Config.apid = "Vedesp32-1";
Config.psk = "vedesp32";
Config.apip=IPAddress(10,1,1,1);
//Config.immediateStart = true;
Config.hostName = "esp32.local";
Config.title = "NBrowser";
Config.autoSave = AC_SAVECREDENTIAL_AUTO;
Config.autoReset = false;
Config.autoReconnect = true;
Config.reconnectInterval = 6;
Config.autoRise = true;
Config.retainPortal = true;
Portal.onDetect(atDetect);
Portal.config(Config);
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <WiFiClient.h>
#include <time.h>
#include <sys/time.h>
#include <AutoConnect.h>
#define IND 2
#define BUZZER 5
#define SWITCH_ON "True"
#define SWITCH_OFF "False"
#define CREDENTIAL_OFFSET 0
const char* URI = "/_ac";
TimerHandle_t wifiReconnectTimer;
AutoConnect Portal;
void pinInit() {
pinMode(BUZZER, OUTPUT);
pinMode(IND, OUTPUT);
}
void connectToWifi() {
Serial.println("Connecting to Wi-Fi... ->");
if (WiFi.status() == WL_CONNECTED) {
delay(5000);
Serial.print(".");
}
}
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch (event) {
case SYSTEM_EVENT_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(BUZZER, HIGH);
digitalWrite(IND, HIGH);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
digitalWrite(IND, LOW);
xTimerStart(wifiReconnectTimer, 0);
break;
}
}
void setup() {
Serial.begin(115200);
Serial.println();
pinInit();
digitalWrite(IND, LOW);
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
WiFi.onEvent(WiFiEvent);
AutoConnectConfig Config;
//Config.bootUri=URI;
Config.homeUri="/_ac";
Config.apid = "Ved";
Config.psk = "vedesp32";
Config.apip=IPAddress(10,1,1,1);
//Config.immediateStart = true;
Config.hostName = "esp32.local";
Config.title = "NBrowser";
Config.autoSave = AC_SAVECREDENTIAL_AUTO;
Config.autoReset = false; // Not reset the module even by intentional disconnection using AutoConnect menu.
Config.autoReconnect = true; // Reconnect to known access points.
Config.reconnectInterval = 6; // Reconnection attempting interval is 3[min].
Config.autoRise = true;
Config.retainPortal = true; // Keep the captive portal open.
Portal.onDetect(atDetect);
Portal.config(Config);
// Start
if (Portal.begin()) {
Serial.println("WiFi connected: " + WiFi.localIP().toString());
digitalWrite(IND, HIGH);
}
connectToWifi();
}
bool atDetect(IPAddress& softapIP) {
Serial.println("Captive portal started, SoftAP IP:" + softapIP.toString());
return true;
}
void loop() {
Portal.handleClient();
}

Arduino web socket autoreconnect

I am using 2 esp8266, both connected to same network. Esp1 send some data to esp2 using websocket. So basically esp2 connect to esp1 websocket and read data.
My problem is that if esp1 is restarted, after is up again, esp2 does not connect anymore to it and needs restart to connect
This is code I am using on esp2
#include <ESP8266WiFi.h>
#include <WebSocketsClient.h>
#include <ESP8266WebServer.h>
#include <SoftwareSerial.h>
#define USE_SERIAL Serial
#define LEDS 0 //Status led
WebSocketsClient webSocket;
SoftwareSerial COM(5, 4);
long previousMillis = 0;
long interval = 50;
String data;
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
switch(type) {
case WStype_DISCONNECTED:
yield();
break;
case WStype_CONNECTED: {
webSocket.sendTXT("Connected");
}
yield();
break;
case WStype_TEXT:
if(payload[0] == '#') {
uint32_t dataz = (uint32_t) strtol((const char *) &payload[1], NULL, 10);
if (dataz < 99911) {
data = "0" + String(dataz);
}
else {
data = String(dataz);
}
}
yield();
if (data.length() == 6 ) {
COM.print('<'); // start marker
COM.print(data);
COM.println('>'); // end marker
}
break;
}
}
void setup() {
pinMode(LEDS, OUTPUT);
digitalWrite(LEDS, LOW);
for(uint8_t t = 4; t > 0; t--) {
delay(1000);
}
WiFi.mode(WIFI_STA);
WiFi.begin("xxx", "xxx");
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
}
// server address, port and URL
webSocket.begin("192.168.0.30", 81, "/");
// event handler
webSocket.onEvent(webSocketEvent);
// use HTTP Basic Authorization this is optional remove if not needed
//webSocket.setAuthorization("user", "Password");
// try ever 5000 again if connection has failed
webSocket.setReconnectInterval(5000);
digitalWrite(LEDS, HIGH);
}
void loop() {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
webSocket.loop();
}
}
I would need some help to make it reconnect when the esp1 is available again after was disconnected
Thank you very much
webSocket.loop(); should be outside of if statement.

Processing Code "Error, disabling_serialEvent() in Arduino

I receive this error when trying to run my arduino and Processing
Error, disabling serialEvent() for /dev/cu.usbmodem1451 null
I am running process 2 and Arduino 1.6.5 on a MAC OSX 10.9.5
I am super new to processing and arduino . I am just trying to use three potentiometers to control the RGB values of the background color.
Arduino code:
int potPin = 0;
//int potPinB = 1;
//int potPinC = 2;
void setup()
{
Serial.begin(9600);
}
void loop()
{
int val = map(analogRead(potPin), 0, 1023, 0, 255);
Serial.println(val);
delay(500);
//int valB = map(analogRead(potPinB), 0, 1023, 0, 255);
//Serial.println(valB);
//delay(50);
//int valC = map(analogRead(potPinA), 0, 1023, 0, 255);
//Serial.println(valC);
//delay(50);
}
Processing code:
import processing.serial.*;
Serial port;
float val = 0;
//float valB = 1; // another analog input
//float valC = 2; // another analog input
void setup()
{
size(500, 500);
port = new Serial(this, "/dev/cu.usbmodem1451", 9600);
port.bufferUntil('\n');
if (frame != null);
frame.setResizable(true);
}
void draw ()
{
background(val,255,150);
}
void serialEvent (Serial port)
{
val = float(port.readStringUntil('\n'));
}
You might be getting an error in serialEvent which you should be handling (perhaps the float conversion). Also, if you're using bufferUntil(), you shouldn't need readStringUntil().
Try something like this:
import processing.serial.*;
Serial port;
float val = 0;
//float valB = 1; // another analog input
//float valC = 2; // another analog input
void setup()
{
size(500, 500);
port = new Serial(this, "/dev/cu.usbmodem1451", 9600);
port.bufferUntil('\n');
if (frame != null);
frame.setResizable(true);
}
void draw ()
{
background(val,255,150);
}
void serialEvent (Serial port)
{
try{
val = float(port.readString());
}catch(Exception e){
e.printStackTrace();
}
}
When simply reading a single value, readChar() or simply read() should work.
If the above works. You should be able to send multiple values.
Initially you can send a csv like formatter line:
arduinoR,arduinoG,arduinoB\n
which you can then read as a string, split() it into an array of 3 values, then convert each array element from String to int.
Update
Here an example:
import processing.serial.*;
int r, g, b;
void setup() {
try {
new Serial(this, "/dev/tty.usbmodemfa141", 9600).bufferUntil('\n');
}
catch(Exception e) {
println("check settings above and usb cable, something went wrong:");
e.printStackTrace();
}
}
void draw() {
background(r, g, b);
}
void serialEvent(Serial s) {
String data = s.readString();
try {
String[] rgb = data.trim().split(",");
print(rgb);
if(rgb.length == 3){
r = int(rgb[0]);
g = int(rgb[1]);
b = int(rgb[2]);
}
}
catch(Exception e) {
e.printStackTrace();
}
}
Later on you can look at sending data as binary: exactly 3 bytes (r,g,b).
Have fun :)

Why i am not able to read multiple strings in the server file?

While working in client-server programming, I have passed 3 strings in client, which will be received by server and it should be printed in there 3 times. (i.e I have used a 'for' loop which will do the read & write operations in client & server side respectively.), but in server only the 1st string is getting printed.
Please explain,
Here is my code
server.c
#include "head.h"
void readstr(int connfd ,char [][20]);
//void writestr(char * ,int);
int main(int c ,char *v[])
{
// socket declarations,etc
sd =socket( AF_INET ,SOCK_STREAM ,0);
// Binding socket
retbind =bind(sd ,(struct sockaddr*)&serveraddress ,sizeof(serveraddress
));
listen(sd ,4);
for(;;)
{
printf("i am waiting for client\n");
len =sizeof(cliaddr);
connfd = accept(sd ,(struct sockaddr*)&cliaddr ,&len);
readstr(connfd ,databuf);
close(connfd);
}
return 0;
}
void readstr(int connfd ,char str[3] [20])
{
int pointer=0 ,i=0, n,pos=0;
memset(str ,'\0',sizeof(str));
for(i=0;i<3;i++)
{
while((n=read(connfd ,str[i] ,20)) >>0)
{
printf("Looping while\n");
pos =pos +n;
}
str[i][pos] ='\0';
}
for(i=0;i<3;i++)
{
printf("\n%s",str[i]);
}
}
client.c
#include "head.h"
void send1(int ,char*);
int main(int c,char*v[])
{
//Socket declarations, etc..
sd = socket(AF_INET ,SOCK_STREAM ,0);
//Connect
if(connect(sd,(struct sockaddr*)&serveraddress ,sizeof(serveraddress)) <
0)
{
printf("cannot connect to server");
exit(1);
}
for(i=0;i<3;i++)
{
memset(buf ,'\0',sizeof(buf));
printf("\n Enter the string : ");
fgets(buf[i],20,stdin);
len =strlen(buf[i]);
if(buf[i][len] =='\n')
buf[i][len]='\0';
send1(sd ,(char *)buf);
}
shutdown(sd ,SHUT_WR);
}
void send1(int sd ,char *str)
{
int n ,byteswritten =0, wr;
char buf[1024];
strcpy(buf ,str);
n =strlen(buf);
while(byteswritten < n)
{
printf("\nStarting to write in client side\n");
wr = write(sd , buf+byteswritten ,(n-byteswritten));
byteswritten+=wr;
}
printf("\n string sent %s" ,buf);
}
In server.c in readstr() you are not setting pos to zero before the next for iteration.
Also, there is strange line:
while((n=read(connfd ,str[i] ,20)) >>0)
Note ">>".

Resources