I2C onReceive-handler called only once - arduino

I'm having trouble communicating between Arduino's over I2C. For some reason, the onReceive handler is only called once.
Master Code (sender):
#include <Wire.h>
#include "i2csettings.h" // defines address
void setup()
{
Wire.begin(I2C_MASTER_ADDRESS);
}
void loop()
{
Wire.beginTransmission(I2C_SLAVE_ADDRESS);
Wire.write(0x11);
Wire.endTransmission();
delay(1000);
}
Slave Code (receiver):
#include <Wire.h>
#include "i2csettings.h"
void takeAction(int);
void setup()
{
Serial.begin(9600);
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(takeAction);
}
void loop()
{}
void takeAction(int nBytes)
{
Serial.println("Action!");
}
The idea in this test-setup is to have the sender send a byte every second, and let the receiver act on this by printing a message. However, the message is only printed once. When I reset the Slave, it's printed again, but just once.
Any ideas where this may come from?

You have to make sure you read all the bytes from the stream.
Other wise it seems to block.
Make your event handler look like this. So you can call it multiple times.
void takeAction(int nBytes)
{
Serial.println("Action!");
while(Wire.available())
{
Wire.read();
}
return;
}

Related

Use Serial in Arduino as variable

I would like to choose which Serial should be used on my Mega (e.g. Serial for development & testing, and then Serial3 for communication with another board). I came with this code:
HardwareSerial HWSerial = Serial; //or Serial1, Serial2, Serial3
void setup() {
HWSerial.begin(115200);
}
void loop() {
HWSerial.println("Hello world!");
delay(1000);
}
However, this produces only first two bytes and a NUL ("He␀").
What am I doing wrong?
Note: I know I could use
HardwareSerial* HWSerial = &Serial; //or Serial1, Serial2, Serial3
void setup() {
HWSerial->begin(115200);
}
void loop() {
HWSerial->println("Hello world!");
delay(1000);
}
which works. I was, however, in fact planning to use ArduinoJSON and the serializeJson(JSONObj, serial) function which won't accept a pointer, so I'm stuck there - and my approach compiles, but again, produces only first two bytes...

Get time with API in Arduino

I'm trying to get the current local time with an API. I am using a WEMOS D1 Mini and the get method with blynk to return JSON from the API and store it.
I use this code
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <BlynkSimpleEsp8266.h>
String json;
char auth[] = "";
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
BLYNK_WRITE(V0) {
json = param.asStr();
}
void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
}
void loop() {
Blynk.run();
Blynk.virtualWrite(V0, "https://api.bot-dev.org/time/");
JsonObject& root = jsonBuffer.parseObject(json);
long time = root[String("ENtime")];
}
But i cant receive time in long time variable.
You can do that in simpler way.
You need to add WebHook widget to your app. In the webhoook widget you need to put https://api.bot-dev.org/time/ url. And assign this widget to the virtual pin, let's say V0. Webhook widget will return response to your hardware after it was triggered. So your code should look like that:
BLYNK_WRITE(V0) {
//here you'll get response from the webhook
json = param.asStr();
}
void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
}
void loop() {
Blynk.run();
//trigger the webhook
Blynk.virtualWrite(V0, 1); //you can send any value to trigger webhook
}
Have in mind that you need also to move out Blynk.virtualWrite from main loop in order to avoid flooding.
Here is more details regarding the webhook widget.

Conflict between Arduino delay function and SoftwareSerial

It seems that I have a conflict between SoftwareSerial and the delay function on my Arduino (GeekCreit bought on Banggood). I am trying to use SoftwareSerial to send AT commands to an ESP-01.
When I perform:
#include <SoftwareSerial.h>;
SoftwareSerial esp8266(8,9);
void setup() {
Serial.begin(9600);
while (!Serial) ;
esp8266.begin(9600);
esp8266.println("AT");
}
void loop() {
if(esp8266.available()) {
while(esp8266.available()) {
Serial.print(esp8266.read());
}
}
}
Everything works well, the AT command is sent and I receive the response from my ESP.
But when I add a delay before sending the AT command, nothing happens: no command sent, no answer from the ESP.
#include <SoftwareSerial.h>;
SoftwareSerial esp8266(8,9);
void setup() {
Serial.begin(9600);
while (!Serial) ;
esp8266.begin(9600);
delay(2000);
esp8266.println("AT");
}
void loop() {
if(esp8266.available()) {
while(esp8266.available()) {
Serial.print(esp8266.read());
}
}
}
Am I doing something wrong, has someone experienced the same problem?
I have tried to use AltSoftSerial instead but I have the same issue with it.

Out of time Timer5 interrupt Arduino

I have this code , I try to restart Timer5 when it out of time. But i can't, may you help me ?
#include <TimerFive.h>
#include <TimerOne.h>
#include <openGLCD.h>
#define OLDWAY
unsigned long timer5_started=0;
void setup() {
Serial.begin(9600);
Timer1.stop();
Timer1.detachInterrupt();
Timer1.initialize(500000);
Timer1.attachInterrupt(Timer1Handle);
Timer1.start();
Timer5.stop();
Timer5.detachInterrupt(); //detach interrupt
Timer5.initialize(100000);
Timer5.attachInterrupt(Timer5Handle);
Timer5.start();
///---
}
void loop() {
while(1){
Serial.println("loop...");
delay(500);
}
}
void Timer5Handle(){
timer5_started=millis();
Serial.println("timer 5...");
while(1){
int a=0;
}
}
void Timer1Handle(){
if(millis()-timer5_started>100000){
Serial.println("restart...");
Timer5.restart();
}
}
When Timer5 out of time, the Interupt is stop, how can i restart it ?
When Timer5 out of time, the Interupt is stop, how can i restart it ?
Well, I don't even understand what are you trying to do in that interrupt handler:
void Timer5Handle(){
timer5_started=millis();
Serial.println("timer 5...");
while(1){
int a=0;
}
}
However your interrupt handler is called in actual IRS, so everything else stops including all other Interrupts (including millis counting and delays). And because of infinite loop, it's forever. Interrupt handler should be as short as possible to ensure others are not missed or so.

A simple Arduino alarm is not working

Using the alarm library, I don't get the alarm to work:
#include <Time.h>
#include <TimeAlarms.h>
void setup()
{
Serial.begin(9600);
while (!Serial)
{
;
}
setTime(8,29,0,1,1,10); // set time to 8:29:00am Jan 1 2010
Alarm.timerRepeat(15, Repeats);
}
void Repeats()
{
Serial.print("alarmed timer!");
digitalWrite(10,1);
}
void loop()
{
}
I suppose you are using this library.
If you read in the help, you can see this:
Normal Running Usage
Alarm.delay(milliseconds); Alarms and Timers are only checks and their
functions called when you use this delay function. You can pass 0 for
minimal delay. This delay should be used instead of the normal Arduino
delay(), for timely processing of alarms and timers.
so in order for the alarms to be called, you have to add this:
void loop(){
Alarm.delay(1000); // wait one second between clock display
}
If you prefer to check the alarm faster, you can use a lower delay (e.g. 100). You can also use 0, so the function doesn't block, but it is not mandatory for your application.
By the way, I THINK (so I can be wrong) that the call to setTime is used just by the other functions, not by the timer. So you can omit it. Moreover you missed the pinmode statement..
In the end.. Try this code and let us know.
#include <Time.h>
#include <TimeAlarms.h>
void setup()
{
Serial.begin(9600);
while (!Serial) ;
pinMode(10, OUTPUT);
Alarm.timerRepeat(15, Repeats);
}
void Repeats()
{
Serial.print("alarmed timer!");
digitalWrite(10,1);
}
void loop()
{
Alarm.delay(500);
}
Add Alarm.delay(0); this way your program won't freeze and your alarm will work...

Resources