Connection problem of ESP8266 ESP-01 arduino uno to cayenne - arduino

I am using the ESP8266 Wi-Fi shield to connect Arduino to the cayenne server. However once connect the chip to the access point it will heat up and sometimes will lagging. After that, it shows some message but the Cayenne server didn't connect to the Arduino. Every widget can not be operated (No response when clicking a button, temperature value unchanged, etc.). Can anyone solve this issue? It is important for my course work. I am using Arduino Uno and ESP8266 ESP-01 chip. We have tried different styles of code to upload data to cayenne server but they didn't work(Below include 3 versions)
Finale 1 Version(Cayenne out) :
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266Shield.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <virtuabotixRTC.h>
//Real+Virtual
#define LED_PIN 5
#define temp_sensor 4
#define EspSerial Serial
//Virtual
#define Power_sensor 9
#define DayPower 10
#define MonthPower 11
#define LED_PWM 12
//SSID
char ssid[] = "TP-LINK_MWNg";
char password[] = "mwngpass";
char username[] = "743674368676328742somenumbers";
char mqtt_password[] = "743674368676328742somenumbers";
char client_id[] = "743674368676328742somenumbers";
ESP8266 wifi(&EspSerial);
//Temperature setup
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
//Power sensor
const int analogInPin = A0;
int sensorValue = 0; // value read from the pot
float MAXValue = 0; // value output to the PWM (analog out)
float Power = 0;
int PWM = 0;
//Time
int curSec = 0;
int curMin = 0;
int curHour = 0;
int curDay = 0;
virtuabotixRTC myRTC(6, 7, 8);
unsigned PowerInDay = 0;
unsigned PowerInMonth = 0;
void setup() {
// put your setup code here, to run once:
sensors.begin();
EspSerial.begin(115200);
delay(10);
Cayenne.begin(username, mqtt_password, client_id, wifi, ssid, password);
pinMode(LED_PIN, OUTPUT);
analogWrite(LED_PIN, PWM);
curSec = myRTC.seconds;
curMin = myRTC.minutes;
curHour = myRTC.hours;
curDay = myRTC.dayofmonth;
//test
}
void loop() {
Cayenne.loop();
myRTC.updateTime();
if ( curSec != myRTC.seconds ) {
PowerInDay += Power;
curSec = myRTC.seconds;
}
if (curDay != myRTC.dayofmonth) {
PowerInMonth += PowerInDay;
PowerInDay = 0;
curDay = myRTC.dayofmonth;
}
if (curDay > myRTC.dayofmonth) {
PowerInMonth = 0;
}
Serial.print(myRTC.dayofmonth);
Serial.print('/');
Serial.print(myRTC.month);
Serial.print('/');
Serial.print(myRTC.year);
Serial.print('/');
Serial.print(' ');
Serial.print(myRTC.hours);
Serial.print(':');
Serial.print(myRTC.minutes);
Serial.print(':');
Serial.print(myRTC.seconds);
Serial.print('\n');
Serial.print(PowerInDay);
Serial.print(' ');
Serial.print(PowerInMonth);
Serial.print('\n');
}
CAYENNE_OUT(temp_sensor)
{
sensors.requestTemperatures();
Cayenne.celsiusWrite(temp_sensor, sensors.getTempCByIndex(0));
}
CAYENNE_OUT(Power_sensor)
{
sensorValue = analogRead(analogInPin);
// map it to the range of the analog out:
if (sensorValue > 0)
MAXValue = sensorValue * 0.00007307;
Power = MAXValue * ((float)PWM / (float)255) * 3.3 * ((float)PWM / (float)255);
// change the analog out value:/
// print the results to the serial monitor:
Serial.print("sensor = ");
Serial.print(sensorValue); //RAW value from analog read :)
Serial.print("\t output = ");
Serial.println(MAXValue * ((float)PWM / (float)255), 3); //Output the current
Serial.print("Power =");
Serial.println(Power, 3);
// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(50);
Cayenne.virtualWrite(Power_sensor, Power, "pow", "w");
}
CAYENNE_OUT(DayPower) {
Cayenne.virtualWrite(DayPower, PowerInDay, "pow", "w");
}
CAYENNE_OUT(MonthPower) {
Cayenne.virtualWrite(MonthPower, PowerInMonth, "pow", "w");
}
CAYENNE_IN(LED_PIN)
{
int currentValue = getValue.asInt();
if (currentValue == 1) {
PWM = 255;
digitalWrite(LED_PIN, HIGH);
} else {
PWM = 0;
digitalWrite(LED_PIN, LOW);
}
//digitalWrite(Relay, HIGH);
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}
CAYENNE_IN(LED_PWM)
{
int value = getValue.asInt(); // 0 to 255
PWM = value;
analogWrite(LED_PIN, value);
}
Finale 2 Version(Cayenne out_Default):
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266Shield.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <virtuabotixRTC.h>
//Real+Virtual
#define LED_PIN 5
#define temp_sensor 4
#define EspSerial Serial
//Virtual
#define Power_sensor 9
#define DayPower 10
#define MonthPower 11
#define LED_PWM 12
//SSID
char ssid[] = "TP-LINK_MWNg";
char password[] = "mwngpass";
char username[] = "743674368676328742somenumbers";
char mqtt_password[] = "743674368676328742somenumbers";
char client_id[] = "743674368676328742somenumbers";
ESP8266 wifi(&EspSerial);
//Temperature setup
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
//Power sensor
const int analogInPin = A0;
int sensorValue = 0; // value read from the pot
float MAXValue = 0; // value output to the PWM (analog out)
float Power = 0;
int PWM = 0;
//Time
int curSec = 0;
int curMin = 0;
int curHour = 0;
int curDay = 0;
virtuabotixRTC myRTC(6, 7, 8);
unsigned PowerInDay = 0;
unsigned PowerInMonth = 0;
void setup() {
// put your setup code here, to run once:
sensors.begin();
EspSerial.begin(115200);
delay(10);
Cayenne.begin(username, mqtt_password, client_id, wifi, ssid, password);
pinMode(LED_PIN, OUTPUT);
analogWrite(LED_PIN, PWM);
curSec = myRTC.seconds;
curMin = myRTC.minutes;
curHour = myRTC.hours;
curDay = myRTC.dayofmonth;
//test
}
void loop() {
Cayenne.loop();
myRTC.updateTime();
if ( curSec != myRTC.seconds ) {
PowerInDay += Power;
curSec = myRTC.seconds;
}
if (curDay != myRTC.dayofmonth) {
PowerInMonth += PowerInDay;
PowerInDay = 0;
curDay = myRTC.dayofmonth;
}
if (curDay > myRTC.dayofmonth) {
PowerInMonth = 0;
}
Serial.print(myRTC.dayofmonth);
Serial.print('/');
Serial.print(myRTC.month);
Serial.print('/');
Serial.print(myRTC.year);
Serial.print('/');
Serial.print(' ');
Serial.print(myRTC.hours);
Serial.print(':');
Serial.print(myRTC.minutes);
Serial.print(':');
Serial.print(myRTC.seconds);
Serial.print('\n');
Serial.print(PowerInDay);
Serial.print(' ');
Serial.print(PowerInMonth);
Serial.print('\n');
}
CAYENNE_OUT_DEFAULT()
{
//Temp sensor-----------------------------------------
sensors.requestTemperatures();
Cayenne.celsiusWrite(temp_sensor, sensors.getTempCByIndex(0));
//Temp sensor-----------------------------------------
//Power sensor-------------------------------------------------
sensorValue = analogRead(analogInPin);
// map it to the range of the analog out:
if (sensorValue > 0)
MAXValue = sensorValue * 0.00007307;
Power = MAXValue * ((float)PWM / (float)255) * 3.3 * ((float)PWM / (float)255);
// change the analog out value:/
// print the results to the serial monitor:
Serial.print("sensor = ");
Serial.print(sensorValue); //RAW value from analog read :)
Serial.print("\t output = ");
Serial.println(MAXValue * ((float)PWM / (float)255), 3); //Output the current
Serial.print("Power =");
Serial.println(Power, 3);
// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(50);
Cayenne.virtualWrite(Power_sensor, Power, "pow", "w");
//Power sensor-------------------------------------------------
//Power Day-------------------------------------------------
Cayenne.virtualWrite(DayPower, PowerInDay, "pow", "w");
//Power Month-------------------------------------------------
Cayenne.virtualWrite(MonthPower, PowerInMonth, "pow", "w");
}
CAYENNE_IN(LED_PIN)
{
int currentValue = getValue.asInt();
if (currentValue == 1) {
PWM = 255;
digitalWrite(LED_PIN, HIGH);
} else {
PWM = 0;
digitalWrite(LED_PIN, LOW);
}
//digitalWrite(Relay, HIGH);
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}
CAYENNE_IN(LED_PWM)
{
int value = getValue.asInt(); // 0 to 255
PWM = value;
analogWrite(LED_PIN, value);
}
Finale 3 Version(Send data with time difference):
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266Shield.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <virtuabotixRTC.h>
//Real+Virtual
#define LED_PIN 5
#define temp_sensor 4
#define EspSerial Serial
//Virtual
#define Power_sensor 9
#define DayPower 10
#define MonthPower 11
#define LED_PWM 12
//SSID
char ssid[] = "TP-LINK_MWNg";
char password[] = "mwngpass";
char username[] = "743674368676328742somenumbers";
char mqtt_password[] = "743674368676328742somenumbers";
char client_id[] = "743674368676328742somenumbers";
ESP8266 wifi(&EspSerial);
//Temperature setup
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
//Power sensor
const int analogInPin = A0;
int sensorValue = 0; // value read from the pot
float MAXValue = 0; // value output to the PWM (analog out)
float Power = 0;
int PWM = 0;
//Time
int curSec = 0;
int curMin = 0;
int curHour = 0;
int curDay = 0;
virtuabotixRTC myRTC(6, 7, 8);
unsigned PowerInDay = 0;
unsigned PowerInMonth = 0;
int lastMillis = 0;
void setup() {
// put your setup code here, to run once:
sensors.begin();
EspSerial.begin(115200);
delay(10);
Cayenne.begin(username, mqtt_password, client_id, wifi, ssid, password);
pinMode(LED_PIN, OUTPUT);
analogWrite(LED_PIN, PWM);
curSec = myRTC.seconds;
curMin = myRTC.minutes;
curHour = myRTC.hours;
curDay = myRTC.dayofmonth;
//test
}
void loop() {
Cayenne.loop();
myRTC.updateTime();
if ( curSec != myRTC.seconds ) {
PowerInDay += Power;
curSec = myRTC.seconds;
}
if (curDay != myRTC.dayofmonth) {
PowerInMonth += PowerInDay;
PowerInDay = 0;
curDay = myRTC.dayofmonth;
}
if (curDay > myRTC.dayofmonth) {
PowerInMonth = 0;
}
// Serial.print(myRTC.dayofmonth);
// Serial.print('/');
// Serial.print(myRTC.month);
// Serial.print('/');
// Serial.print(myRTC.year);
// Serial.print('/');
// Serial.print(' ');
// Serial.print(myRTC.hours);
// Serial.print(':');
// Serial.print(myRTC.minutes);
// Serial.print(':');
// Serial.print(myRTC.seconds);
// Serial.print('\n');
// Serial.print(PowerInDay);
// Serial.print(' ');
// Serial.print(PowerInMonth);
// Serial.print('\n');
if(millis() - lastMillis > 10000 && millis() - lastMillis < 20000 ) {//Send data between 10 - 20 seconds
//Temp sensor-----------------------------------------
sensors.requestTemperatures();
Cayenne.celsiusWrite(temp_sensor, sensors.getTempCByIndex(0));
//Temp sensor-----------------------------------------
}
if(millis() - lastMillis > 20000 && millis() - lastMillis < 30000 ) {//Send data between 20 - 30 seconds
//Power sensor-------------------------------------------------
sensorValue = analogRead(analogInPin);
// map it to the range of the analog out:
if (sensorValue > 0)
MAXValue = sensorValue * 0.00007307;
Power = MAXValue * ((float)PWM / (float)255) * 3.3 * ((float)PWM / (float)255);
// change the analog out value:/
// print the results to the serial monitor:
Serial.print("sensor = ");
Serial.print(sensorValue); //RAW value from analog read :)
Serial.print("\t output = ");
Serial.println(MAXValue * ((float)PWM / (float)255), 3); //Output the current
Serial.print("Power =");
Serial.println(Power, 3);
// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(50);
Cayenne.virtualWrite(Power_sensor, Power, "pow", "w");
//Power sensor-------------------------------------------------
}
if(millis() - lastMillis > 30000 && millis() - lastMillis < 40000 ) {//Send data between 30 - 40 seconds
//Power Day-------------------------------------------------
Cayenne.virtualWrite(DayPower, PowerInDay, "pow", "w");
}
if(millis() - lastMillis > 40000 && millis() - lastMillis < 50000 ) {//Send data between 40 - 50 seconds
//Power Month-------------------------------------------------
Cayenne.virtualWrite(MonthPower, PowerInMonth, "pow", "w");
lastMillis = millis();
}
}
CAYENNE_IN(LED_PIN)
{
int currentValue = getValue.asInt();
if (currentValue == 1) {
PWM = 255;
digitalWrite(LED_PIN, HIGH);
} else {
PWM = 0;
digitalWrite(LED_PIN, LOW);
}
//digitalWrite(Relay, HIGH);
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}
CAYENNE_IN(LED_PWM)
{
int value = getValue.asInt(); // 0 to 255
PWM = value;
analogWrite(LED_PIN, value);
}
Serial monitor message:
AT
ATE0
AT+CIPMUX=1
AT+CWMODE?
AT+CWJAP="TP-LINK_MWNg","mwngpass"
[5618] Connected to WiFi
[5619] Connecting to mqtt.mydevices.com:1883
AT+CIPSTART=1,"TCP","mqtt.mydevices.com",1883
[15636] Network connect failed
AT+CIPSTART=1,"TCP","mqtt.mydevices.com",1883
AT+CIPSEND=1,40
MQIsdp
9c6b2/things/743674368676328742somenumbersAT+CIPSEND=1,16
e7f5ba423/cmd/+
AT+CIPSEND=1,40
AT+CIPSEND=1,40
AT+CIPSEND=1,40
AT+CIPSEND=1,40
1i Zv1/743674368676328742somenumbersAT+CIPSEND=1,40
6b2/things/743674368676328742somenumbersAT+CIPSEND=1,27
f5ba423/data/4temp,c=28.125sensor = 0 output = 0.000
Power =0.000
AT+CIPSEND=1,40
1g

If your module is getting warm its probably a hardwareissue.I guess you use 5V for the esp module which is bad as it only needs 3.3V. It might survive 5V for a short time(moment) but don't stretch your luck. So you have to convert 5V ro 3.3V level shifter. You can not use the Arduino 3.3V output pin because it can not provide the power needed by the ESP (up to 250mA) vs. max 50mA on the Arduino (UNO) 3.3V pin.
The schematic shortly explained:
The ESP's VCC pin is powered by the 3.3V output pin of the voltage regulator (AMS1117 in the grphic).
The 10uF capacitor is connected to the output pins to stabilize the regulator.
The CH_PD pin must also be connected to 3.3V.
The GND pin is obviously connected to ground.
The ESP's TXD pin can be connected directly to the RX pin of Arduino (emulated on pin 6).
The ESP's RXD pin is connected to the TX pin of Arduino (emulated on pin 7) through the level shifter.
The last two can be changed depending if you use hardware or software serial EDIT
As you use rtc it makes no sense to update the time every loop this will crash your connection. Either do it every x hours and make sure with if/else that nochyenne loop() is running. It makes no sense to sync time every x millis() the syncing of time every hourisenough foryour scenario, I would go for once a day

Related

Arduino I2C Slave to Master communication problem

I am having a problem with reading random data in my Arduino Mega (Master) from my Arduino Uno (Slave) while using I2C communication.
Some background: I am reading Encoder data from the Uno and sending to the Mega via I2C communication. The encoder data is been used in the MEga to adjust the speed of a motor so that the revolutions per second of the different wheels have the same value.
The issue of reading random data arises when I include an IF condition or function.
Even if the IF condition included is an empty one or a call to function which has an empty body it starts to read random wrong data from the Uno.
If i don't have the adjusting part (IF condition/ function) of the code the reading of the data from the Uno works fine.
If anybody can help, it would be greatly appreciated.
Master Code:
#include <SoftwareSerial.h>
#include <SabertoothSimplified.h>
// Include the required Wire library for I2C<br>#include
#include <Wire.h>
// RX on pin 17 (to S2), TX on pin 16 (to S1).
SoftwareSerial SWSerial(NOT_A_PIN, 16);
// Use SWSerial as the serial port.
SabertoothSimplified ST(SWSerial);
//////////////////ENCODER DATA//////////////////
unsigned int revolutions_L_rpm = 0;
unsigned int revolutions_R_rpm = 0;
int16_t x = 0;
int16_t y = 0;
////////////////////////////////////////////////
//////////////VARIABLES FOR ADJUST//////////////
int error = 0;
int kp = 12;
int adjusted = 0;
////////////////////////////////////////////////
////////////////////MOTORS//////////////////////
//Declare the arduino pins
int LEDg = 7;
int LEDr = 6;
int LEDy = 5;
int speedVar = 0;
int speedOne = 0;
int speedTwo = 0;
int power;
////////////////////END/////////////////////////
void setup() {
//initlize the mode of the pins
pinMode(LEDg,OUTPUT);
pinMode(LEDr,OUTPUT);
pinMode(LEDy,OUTPUT);
//set the serial communication rate
Serial.begin(9600);
SWSerial.begin(9600);
Wire.begin();
}
void loop()
{
//check whether arduino is reciving signal or not
if(Serial.available() > 0){
char val = Serial.read();//reads the signal
Serial.print("Recieved: ");
Serial.println(val);
switch(val){
/*********Increase speed by 1 as long as e(triangle) is held*********/
case 'a':
forward();
break;
/*********Decrease speed by 1 as long as g(x) is held*********/
case 'c':
reverse();
break;
/*********Increase speed by 1 as long as e(triangle) is held*********/
case 'd':
turnLeft();
break;
/*********Decrease speed by 1 as long as g(x) is held*********/
case 'b':
turnRight();
break;
/*********Toggle when Circle is held for 5 seconds*********/
case 'f':
toggleSwitch(LEDy);
break;
/*********Toggle when Square is held for 5 seconds*********/
case 'h':
stopMotors();
break;
}
Serial.print("sppedVar = ");
Serial.print(speedVar);
Serial.print("\tleftSpeed: ");
Serial.print(speedOne);
Serial.print("\trightSpeed: ");
Serial.println(speedTwo);
}
Wire.requestFrom(9,4); // Request 4 bytes from slave arduino (9)
byte a = Wire.read();
Serial.print("a: ");
Serial.print(a);
byte b = Wire.read();
Serial.print(" b: ");
Serial.print(b);
byte e = Wire.read();
Serial.print(" --- e: ");
Serial.print(e);
byte f = Wire.read();
Serial.print(" f: ");
Serial.print(f);
x = a;
x = (x << 8) | b;
Serial.print("\tX: ");
Serial.print(x);
y = e;
y = (y << 8) | f;
Serial.print("\tY: ");
Serial.print(y);
revolutions_L_rpm = x;
revolutions_R_rpm = y;
if ((revolutions_L_rpm != revolutions_R_rpm) && (speedVar != 0)){
error = 0;
error = revolutions_L_rpm - revolutions_R_rpm;
adjusted = error/kp;
Serial.print("Error: ");
Serial.print(error);
Serial.print("Error/kp: ");
Serial.println(adjusted);
if ((speedTwo < 20) && (speedTwo > -20)){
speedTwo -= adjusted;
power = speedTwo;
ST.motor(2, -power);
//delay(20);
}
}
// Print out rpm
Serial.print("Left motor rps*100: ");
Serial.print(revolutions_L_rpm);
Serial.print(" ///// Right motor rps*100: ");
Serial.println(revolutions_R_rpm);
// Print out speed
Serial.print("speedOne: ");
Serial.print(speedOne);
Serial.print("\tspeedTwo: ");
Serial.println(speedTwo);
delay(1000);
}
Slave code:
// Include the required Wire library for I2C<br>#include <Wire.h>
#include <Wire.h>
// Checked for main program
volatile boolean counterReady;
// Internal to counting routine
unsigned int timerPeriod;
unsigned int timerTicks;
unsigned long overflowCount;
// The pin the encoder is connected
int encoder_in_L = 2;
int encoder_in_R = 3;
// The number of pulses per revolution
// depends on your index disc!!
unsigned int pulsesperturn = 16;
// The total number of revolutions
int16_t revolutions_L = 0;
int16_t revolutions_R = 0;
int16_t revolutions_L_rpm = 0;
int16_t revolutions_R_rpm = 0;
// Initialize the counter
int16_t pulses_L = 0;
int16_t pulses_R = 0;
byte myData[4];
// This function is called by the interrupt
void count_L() {
pulses_L++;
}
void count_R() {
pulses_R++;
}
void startCounting(unsigned int ms) {
counterReady = false; // time not up yet
timerPeriod = ms; // how many ms to count to
timerTicks = 0; // reset interrupt counter
overflowCount = 0; // no overflows yet
// Reset timer 2
TCCR2A = 0;
TCCR2B = 0;
// Timer 2 - gives us our 1 ms counting interval
// 16 MHz clock (62.5 ns per tick) - prescaled by 128
// counter increments every 8 µs.
// So we count 125 of them, giving exactly 1000 µs (1 ms)
TCCR2A = bit (WGM21) ; // CTC mode
OCR2A = 124; // count up to 125 (zero relative!!!!)
// Timer 2 - interrupt on match (ie. every 1 ms)
TIMSK2 = bit (OCIE2A); // enable Timer2 Interrupt
TCNT2 = 0; // set counter to zero
// Reset prescalers
GTCCR = bit (PSRASY); // reset prescaler now
// start Timer 2
TCCR2B = bit (CS20) | bit (CS22) ; // prescaler of 128
}
ISR (TIMER2_COMPA_vect){
// see if we have reached timing period
if (++timerTicks < timerPeriod)
return;
TCCR2A = 0; // stop timer 2
TCCR2B = 0;
TIMSK2 = 0; // disable Timer2 Interrupt
counterReady = true;
if(counterReady){
Serial.print("Pulses_L: ");
Serial.print(pulses_L);
Serial.print(" Pulses_R: ");
Serial.println(pulses_R);
// multiplying by 100 to get a greater difference to compare
revolutions_L_rpm = (pulses_L * 100) / pulsesperturn;
revolutions_R_rpm = (pulses_R * 100) / pulsesperturn;
// Total revolutions
// revolutions_L = revolutions_L + (pulses_L / pulsesperturn);
// revolutions_R = revolutions_R + (pulses_R / pulsesperturn);
pulses_L = 0;
pulses_R = 0;
}
}
void requestEvent() {
myData[0] = (revolutions_L_rpm >> 8) & 0xFF;
myData[1] = revolutions_L_rpm & 0xFF;
myData[2] = (revolutions_R_rpm >> 8) & 0xFF;
myData[3] = revolutions_R_rpm & 0xFF;
Wire.write(myData, 4); //Sent 4 bytes to master
}
void setup() {
Serial.begin(9600);
pinMode(encoder_in_L, INPUT);
pinMode(encoder_in_R, INPUT);
attachInterrupt(0, count_L, RISING); //attachInterrupt(digitalPinToInterrupt(encoder_in_L, count_L, RISING);
attachInterrupt(1, count_R, RISING); //attachInterrupt(digitalPinToInterrupt(encoder_in_R, count_R, RISING);
// Start the I2C Bus as Slave on address 9
Wire.begin(9);
// Attach a function to trigger when something is received.
Wire.onRequest(requestEvent);
}
void loop() {
// stop Timer 0 interrupts from throwing the count out
byte oldTCCR0A = TCCR0A;
byte oldTCCR0B = TCCR0B;
TCCR0A = 0; // stop timer 0
TCCR0B = 0;
startCounting (1000); // how many ms to count for
while (!counterReady)
{ } // loop until count over
// Print out rpm
Serial.print("Left motor rps: ");
Serial.println(revolutions_L_rpm);
Serial.print("Right motor rps: ");
Serial.println(revolutions_R_rpm);
// Print out revolutions
// Serial.print("Left motor revolution count: ");
// Serial.println(revolutions_L);
// Serial.print("Right motor revolution count: ");
// Serial.println(revolutions_R);
// restart timer 0
TCCR0A = oldTCCR0A;
TCCR0B = oldTCCR0B;
delay(200);
}

Arduino Uno low memory available

i'm trying to do a communication over ethernet using ENC28J60 and Arduino Uno and run 3 task . I have a little problem with my arduino code. My code is compiling but i get the following error : "Low memory available, stability problems may occur." and the led on the board is blinking very fast. I guess that the board is trying to alocate memory but he faild. Any idea what can i do ?
#include <Arduino_FreeRTOS.h>
#include "HX711.h"
#include <PID_v1.h>
#include <string.h>
//#include <SPI.h>
#include <UIPEthernet.h>
#define configUSE_IDLE_HOOK 0
// FreeRTOS tasks
void TaskPrimaryControlLoop(void *pvParameters);
void TaskConcentrationControlLoop(void *pvParameters);
void TaskIdle(void *pvParameters);
/* Weigth Cells */
#define hx_pf_dout 3
#define hx_pf_clk 2
#define hx_c_dout 5
#define hx_c_clk 4
HX711 pf_scale(hx_pf_dout, hx_pf_clk);
HX711 c_scale(hx_c_dout, hx_c_clk);
float pf_factor = -236000;
float c_factor = -203000;
float p_weigth = 0; // (kg, 0.000) primary liquid weigth
float p_l_weigth = 0; // (kg, 0.000) primary liquid last weigth
float c_weigth = 0; // (kg, 0.000) concentrate liquid weigth
float c_l_weight = 0; // (kg, 0.000) concentrate liquid last weigth
/* h bridge config */
#define speed_p 9
#define forward_p 7
#define backward_p 8
#define speed_c 6
#define forward_c A0
#define backward_c A1
double p_pump = 0; // 0-255 pwm pump output
double c_pump = 0; // 0-255 pwm pump output
//// PID parameters
// Primary Control Loop
#define p_kp 250.0
#define p_ki 25.0
// Concentration Control Loop
#define c_kp 250.0
#define c_ki 25.0
double p_pv = 0; // (%) primary flow value
double c_pv = 0; // (%) concentration flow value
double p_sp = 0; // (l/min) primary flow setpoint
double c_sp_proc = 0; // % concentration
double c_sp = 0; // (l/min) concentration setpoint
PID pid_pcl(&p_pv, &p_pump, &p_sp, p_kp,p_ki,0.0, DIRECT);
PID pid_ccl(&c_pv, &c_pump, &c_sp, c_kp,c_ki,0.0, DIRECT);
/* Communication Ethernet */
#define MAX_STRING_LEN 32
const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 2);
IPAddress myDns(192,168,1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
// telnet defaults to port 23
EthernetServer server(23);
//EthernetClient client;
boolean alreadyConnected = false; // whether or not the client was connected previously
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
}
pinMode(forward_p, OUTPUT);
pinMode(backward_p, OUTPUT);
pinMode(forward_c, OUTPUT);
pinMode(backward_c, OUTPUT);
pinMode(speed_p, OUTPUT);
pinMode(speed_c, OUTPUT);
digitalWrite(backward_p, HIGH);
digitalWrite(backward_c, HIGH);
digitalWrite(forward_p, LOW);
digitalWrite(forward_c, LOW);
pf_scale.set_scale(pf_factor);
c_scale.set_scale(c_factor);
//pf_scale.tare();
//c_scale.tare();
pid_ccl.SetMode(AUTOMATIC);
pid_pcl.SetMode(AUTOMATIC);
xTaskCreate(
TaskPrimaryControlLoop
, (const portCHAR *)"PrimaryControlLoop" // A name just for humans
, 128 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL
, 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, NULL );
xTaskCreate(
TaskConcentrationControlLoop
, (const portCHAR *)"ConcentrationControlLoop" // A name just for humans
, 128 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL
, 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, NULL );
xTaskCreate(
TaskIdle
, (const portCHAR *)"Idle" // A name just for humans
, 512 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL
, 0 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, NULL );
}
void loop() {
}
void TaskPrimaryControlLoop(void *pvParameters)
{
//(void) pvParameters;
for (;;)
{
p_weigth = pf_scale.get_units(1);
p_pv = (p_l_weigth - p_weigth)*100;
if(p_pv < 0) p_pv = 0;
pid_pcl.Compute();
analogWrite(speed_p, p_pump);
p_l_weigth = p_weigth;
vTaskDelay(200 / portTICK_PERIOD_MS); // 200 ms sample time
}
}
void TaskConcentrationControlLoop(void *pvParameters)
{
//(void) pvParameters;
for (;;)
{
c_weigth = c_scale.get_units(1);
c_pv = (c_l_weight - c_weigth)*100;
if(c_pv < 0) c_pv = 0;
c_sp = p_sp * (c_sp_proc/100);
pid_ccl.Compute();
analogWrite(speed_c, c_pump);
c_l_weight = c_weigth;
vTaskDelay(200 / portTICK_PERIOD_MS); // 200 ms sample time
}
}
void TaskIdle(void *pvParameters)
{
//(void) pvParameters;
for(;;){
EthernetClient client = server.available();
// when the client sends the first byte, say hello:
if (client) {
if (!alreadyConnected) {
client.flush();
//Serial.println("We have a new client");
//client.println("Hello, client!");
alreadyConnected = true;
}
}
recvWithStartEndMarkers();
//showNewData();
if(receivedChars[0] == 's'){
p_sp = atof(subStr(receivedChars, ",", 2));
c_sp_proc = int(subStr(receivedChars, ",", 3));
newData = false;
memset(receivedChars, 0, sizeof(receivedChars));
}
// send process values to application
if(receivedChars[0] == 'w'){
Serial.print(p_pv);
Serial.print(",");
Serial.print(p_sp);
Serial.print(",");
Serial.print(int(c_pump));
Serial.print(",");
Serial.print(c_pv);
Serial.print(",");
Serial.print(c_sp);
Serial.print(",");
Serial.print(int(p_pump));
Serial.println();
newData = false;
memset(receivedChars, 0, sizeof(receivedChars));
}
/*
// check commands
while(Serial.available() > 7){
p_sp = Serial.parseFloat();
c_sp_proc = Serial.parseInt();
}
newData = false;
memset(receivedChars, 0, sizeof(receivedChars)
*/
newData = false;
memset(receivedChars, 0, sizeof(receivedChars));
vTaskDelay(1);
}
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
EthernetClient client = server.available();
while (client.available() > 0 && newData == false) {
rc = client.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
// Function to return a substring defined by a delimiter at an index
char* subStr (char* str, char *delim, int index) {
char *act, *sub, *ptr;
static char copy[MAX_STRING_LEN];
int i;
// Since strtok consumes the first arg, make a copy
strcpy(copy, str);
for (i = 1, act = copy; i <= index; i++, act = NULL) {
//Serial.print(".");
sub = strtok_r(act, delim, &ptr);
if (sub == NULL) break;
}
return sub;
}
First thing to do is try to increase the stack depth of your Tasks.
You're currently using 128, 128 and 512.
You can use "StackHighWaterMark" to get the info about the amount of stack space remaining. Try to use this information to "calibrate" the depth of your task. I recommend using at least 40% of free space.
In order to save space in the Arduino memory you can put all the Serial.print in the flash memory, try to use this syntax:
Serial.print(F(","));
Basically you have to add an F in front of the string that you want to print, but you can't do that when you print a variable:
Serial.print(int(c_pump)); // you can't do that here

Arduino LED Controller hanging at startup

I'm trying to code an LED controller that controls the intensity via PWM. However, my issue is that I can't even get to the loop portion, it seems to hang at when I declare my class. I've tried checking to see if any of my functions in my class are causing the issues, but since I can't even get to loop, there must be something wrong within the class. I've written the class and placed it into a library called LED.
The code is somewhat long, but here it is:
#ifndef LED_H
#define LED_H
#include <LiquidCrystal.h>
#include <Button.h>
#include <EEPROM.h>
#include <TimeLib.h>
#include <PWM.h>
class LED
{
public:
LED();
int read_encoder(); //Reads rotary encoder
void clearLCD();
void setAllLed();
void printLCD();
void setOneLed(int);
int setLed(int, // current time in minutes
int, // pin for this channel of LEDs
int, // start time for this channel of LEDs
int, // photoperiod for this channel of LEDs
int, // fade duration for this channel of LEDs
int, // max value for this channel
bool // true if the channel is inverted
);
void menuWizard();
int subMenuWizard(int, int, bool, bool);
void displayMainMenu();
void printMins(int, bool);
void printHMS(byte,byte,byte);
long EEPROMReadlong(long);
void EEPROMWritelong(int, long);
bool pressSelect();
bool pressBack();
void rotateCheck(int&, int, int);
//variables for the LED channels
int minCounter = 0; // counter that resets at midnight.
int oldMinCounter = 0; // counter that resets at midnight.
int ledPins[5]={2,3,5,6,7};
int ledVal[5]={0,0,0,0,0};
// Variables making use of EEPROM memory:
int variablesList[20];
bool invertedLEDs[5]={false,false,false,false,false};
//Backlight Variables
unsigned long backlightIdleMs = 0;
private:
};
#endif // LED_H
And here is the .cpp file:
#define LCD_RS 35 // RS pin
#define LCD_ENABLE 34 // enable pin
#define LCD_DATA4 33 // d4 pin
#define LCD_DATA5 32 // d5 pin
#define LCD_DATA6 31 // d6 pin
#define LCD_DATA7 30 // d7 pin
#define LCD_BACKLIGHT 9 // backlight pin
// Backlight config
#define BACKLIGHT_DIM 10 // PWM value for backlight at idle
#define BACKLIGHT_ON 70 // PWM value for backlight when on
#define BACKLIGHT_IDLE_MS 10000 // Backlight idle delay
#define ENC_A 14
#define ENC_B 15
#define ENC_PORT PINC
#include <LiquidCrystal.h>
#include <Button.h>
#include <EEPROM.h>
#include <TimeLib.h>
#include <PWM.h>
#include "LED.h"
LiquidCrystal lcd(LCD_RS, LCD_ENABLE, LCD_DATA4, LCD_DATA5, LCD_DATA6, LCD_DATA7);
Button goBack=Button(12, PULLDOWN);
Button select=Button(13, PULLDOWN);
LED::LED()
{
InitTimersSafe();
pinMode(LCD_BACKLIGHT, OUTPUT);
lcd.begin(16, 2);
digitalWrite(LCD_BACKLIGHT, HIGH);
lcd.print("sEx LED, V1");
clearLCD();
delay(5000);
analogWrite(LCD_BACKLIGHT, BACKLIGHT_DIM);
if (variablesList[0] > 1440 || variablesList[0] < 0) {
variablesList[0] = 720; // minute to start this channel.
variablesList[1] = 400; // photoperiod in minutes for this channel.
variablesList[2] = 100; // max intensity for this channel, as a percentage
variablesList[3] = 100; // duration of the fade on and off for sunrise and sunset for
// this channel.
variablesList[4] = 720;
variablesList[5] = 400;
variablesList[6] = 100;
variablesList[7] = 100;
variablesList[8] = 720;
variablesList[9] = 400;
variablesList[10] = 100;
variablesList[11] = 100;
variablesList[12] = 720;
variablesList[13] = 400;
variablesList[14] = 100;
variablesList[15] = 100;
variablesList[16] = 720;
variablesList[17] = 400;
variablesList[18] = 100;
variablesList[19] = 100;
}
else {
variablesList[0] = EEPROMReadlong(0); // minute to start this channel.
variablesList[1] = EEPROMReadlong(4); // photoperiod in minutes for this channel.
variablesList[2] = EEPROMReadlong(8); // max intensity for this channel, as a percentage
variablesList[3] = EEPROMReadlong(12); // duration of the fade on and off for sunrise and sunset for
// this channel.
variablesList[4] = EEPROMReadlong(16);
variablesList[5] = EEPROMReadlong(20);
variablesList[6] = EEPROMReadlong(24);
variablesList[7] = EEPROMReadlong(28);
variablesList[8] = EEPROMReadlong(32);
variablesList[9] = EEPROMReadlong(36);
variablesList[10] = EEPROMReadlong(40);
variablesList[11] = EEPROMReadlong(44);
variablesList[12] = EEPROMReadlong(48);
variablesList[13] = EEPROMReadlong(52);
variablesList[14] = EEPROMReadlong(56);
variablesList[15] = EEPROMReadlong(60);
variablesList[16] = EEPROMReadlong(64);
variablesList[17] = EEPROMReadlong(68);
variablesList[18] = EEPROMReadlong(72);
variablesList[19] = EEPROMReadlong(76);
}
}
void LED::printLCD(){lcd.print("test");clearLCD();delay(2000);lcd.print("testing");clearLCD();}
bool LED::pressSelect(){
if (select.uniquePress()){return 1;}
else {return 0;}
}
bool LED::pressBack(){
if (goBack.uniquePress()){return 1;}
else {return 0;}
}
void LED::clearLCD(){
lcd.clear();
}
void LED::displayMainMenu(){
oldMinCounter = minCounter;
minCounter = hour() * 60 + minute();
for (int i=0;i<17;i=i+4){
if (variablesList[i+3] > variablesList[i+1] / 2 && variablesList[i+1] > 0) {
variablesList[i+3] = variablesList[i+1] / 2;
}
if (variablesList[i+3] < 1) {
variablesList[i+3] = 1;
}
}
//check & set any time functions
if (minCounter > oldMinCounter) {
lcd.clear();
}
lcd.setCursor(0, 0);
printHMS(hour(), minute(), second());
lcd.setCursor(0, 1);
lcd.print(ledVal[0]);
lcd.setCursor(4, 1);
lcd.print(ledVal[1]);
lcd.setCursor(8, 1);
lcd.print(ledVal[2]);
}
int LED::read_encoder()
{
static int enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
static int old_AB = 0;
/**/
old_AB <<= 2; //remember previous state
old_AB |= ( ENC_PORT & 0x03 ); //add current state
return ( enc_states[( old_AB & 0x0f )]);
}
int LED::setLed(int mins, // current time in minutes
int ledPin, // pin for this channel of LEDs
int start, // start time for this channel of LEDs
int period, // photoperiod for this channel of LEDs
int fade, // fade duration for this channel of LEDs
int ledMax, // max value for this channel
bool inverted // true if the channel is inverted
) {
int val = 0;
//fade up
if (mins > start || mins <= start + fade) {
val = map(mins - start, 0, fade, 0, ledMax);
}
//fade down
if (mins > start + period - fade && mins <= start + period) {
val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
}
//off or post-midnight run.
if (mins <= start || mins > start + period) {
if ((start + period) % 1440 < start && (start + period) % 1440 > mins )
{
val = map((start + period - mins) % 1440, 0, fade, 0, ledMax);
}
else
val = 0;
}
if (val > ledMax) {
val = ledMax;
}
if (val < 0) {
val = 0;
}
if (inverted) {
pwmWrite(ledPin, map(val, 0, 100, 255, 0));
}
else {
pwmWrite(ledPin, map(val, 0, 100, 0, 255));
}
return val;
}
void LED::printMins(int mins, //time in minutes to print
bool ampm //print am/pm?
) {
int hr = (mins % 1440) / 60;
int mn = mins % 60;
if (hr < 10) {
lcd.print(" ");
}
lcd.print(hr);
lcd.print(":");
if (mn < 10) {
lcd.print("0");
}
lcd.print(mn);
}
void LED::printHMS (byte hr,
byte mn,
byte sec //time to print
)
{
if (hr < 10) {
lcd.print(" ");
}
lcd.print(hr, DEC);
lcd.print(":");
if (mn < 10) {
lcd.print("0");
}
lcd.print(mn, DEC);
lcd.print(":");
if (sec < 10) {
lcd.print("0");
}
lcd.print(sec, DEC);
}
//EEPROM write functions
long LED::EEPROMReadlong(long address)
{
//Read the 4 bytes from the eeprom memory.
long four = EEPROM.read(address);
long three = EEPROM.read(address + 1);
long two = EEPROM.read(address + 2);
long one = EEPROM.read(address + 3);
//Return the recomposed long by using bitshift.
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}
void LED::EEPROMWritelong(int address, long value)
{
//Decomposition from a long to 4 bytes by using bitshift.
//One = Most significant -> Four = Least significant byte
byte four = (value & 0xFF);
byte three = ((value >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);
//Write the 4 bytes into the eeprom memory.
EEPROM.write(address, four);
EEPROM.write(address + 1, three);
EEPROM.write(address + 2, two);
EEPROM.write(address + 3, one);
}
void LED::setAllLed(){
int j=0;
for (int i=0;i<17;i=i+4){
int a=i;int b=i+1;int c=i+2;int d=i+3;
ledVal[j] = setLed(minCounter, ledPins[j], variablesList[a], variablesList[b], variablesList[c], variablesList[d], invertedLEDs[j]);
j++;
}
}
void LED::setOneLed(int channel){
int j=channel;
int i=0;
if(channel==1){i+=4;}
if(channel==2){i+=8;}
if(channel==3){i+=12;}
if(channel==4){i+=16;}
int a=i;int b=i+1;int c=i+2;int d=i+3;
ledVal[j] = setLed(minCounter, ledPins[j], variablesList[a], variablesList[b], variablesList[c], variablesList[d], invertedLEDs[j]);
}
void LED::rotateCheck(int& menuCount, int minMenu, int maxMenu){
while (menuCount!=0){
int rotateCount;
rotateCount=read_encoder();
if (rotateCount) {
menuCount+=rotateCount;
if (menuCount<minMenu){menuCount==maxMenu;}
if (menuCount>maxMenu){menuCount==minMenu;}
clearLCD();
}
}
}
void LED::menuWizard(){
int menuCount=1;
String menuList[6]={"Time","LED Max","LED Start","LED End","Fade Length","Ch Override"};
String channelList[5]={"1","2","3","4","5"};
while (menuCount!=0){
rotateCheck(menuCount,1,6);
lcd.setCursor(0, 0);
lcd.print(menuList[menuCount-1]);
clearLCD();
if (goBack.isPressed()){
menuCount=0;
}
if (pressSelect() && menuCount!=0){
int timeMode=1;
int channelCount=0;
bool goBack=0;
while (goBack!=1){
if (menuCount==1){
if (pressSelect()){
timeMode++;
if (timeMode>2){timeMode=1;}
}
int timeAdjDetect=read_encoder();
if (timeMode==1){
if (timeAdjDetect){
if (timeAdjDetect>0){adjustTime(SECS_PER_HOUR);}
if (timeAdjDetect<0) {adjustTime(-SECS_PER_HOUR);}
}
lcd.setCursor(0, 0);
lcd.print("Set Time: Hrs");
lcd.setCursor(0, 1);
printHMS(hour(), minute(), second());
}
else{
if (timeAdjDetect){
if (timeAdjDetect>0){adjustTime(SECS_PER_MIN);}
if (timeAdjDetect<0) {adjustTime(-SECS_PER_MIN);}
}
lcd.setCursor(0, 0);
lcd.print("Set Time: Mins");
lcd.setCursor(0, 1);
printHMS(hour(), minute(), second());
}
clearLCD();
}
else{
rotateCheck(channelCount,0,4);
lcd.setCursor(0,0);
lcd.print("Select Channel");
lcd.setCursor(0,1);
lcd.print(channelList[channelCount]);
clearLCD();
if (pressSelect()){
if (menuCount==2){
subMenuWizard(2,channelCount,0,0);
}
if (menuCount==3){
subMenuWizard(0,channelCount,1,0);
}
if (menuCount==4){
subMenuWizard(1,channelCount,1,1);
}
if (menuCount==5){
subMenuWizard(3,channelCount,1,0);
}
}
}
if (pressBack()){goBack=1;}
}
}
}
for (int i=0;i<20;i++){
int j=0;
EEPROMWritelong(j, variablesList[i]);
j+=4;
}
}
int LED::subMenuWizard(int i, int channel, bool time, bool truetime){
if (channel==1){i=i+4;}
if (channel==2){i=i+8;}
if (channel==3){i=i+12;}
if (channel==4){i=i+16;}
while (!pressBack()){
if (time==0){
rotateCheck(variablesList[i],0,100);
lcd.setCursor(0,0);
lcd.print("Set:");
lcd.setCursor(0,1);
lcd.print(variablesList[i]);
setOneLed(channel);
clearLCD();
}
else{
if (truetime){
rotateCheck(variablesList[i],0,1439);
lcd.setCursor(0,0);
lcd.print("Set:");
lcd.setCursor(0,1);
printMins(variablesList[i] + variablesList[i-1], true);
clearLCD();
}
else {
rotateCheck(variablesList[i],0,1439);
lcd.setCursor(0,0);
lcd.print("Set:");
lcd.setCursor(0,1);
printMins(variablesList[i], true);
clearLCD();
}
setOneLed(channel);
}
}
}
and finally, the .ino file:
#define LCD_BACKLIGHT 9 // backlight pin
#define BACKLIGHT_DIM 10 // PWM value for backlight at idle
#define BACKLIGHT_ON 70 // PWM value for backlight when on
#define BACKLIGHT_IDLE_MS 10000 // Backlight idle delay
#include <LED.h>
//Initialize buttons
int buttonCount = 1;
LED main;
void setup() {
};
void loop() {
/* main.setAllLed();
//turn the backlight off and reset the menu if the idle time has elapsed
if (main.backlightIdleMs + BACKLIGHT_IDLE_MS < millis() && main.backlightIdleMs > 0 ) {
analogWrite(LCD_BACKLIGHT, BACKLIGHT_DIM);
main.clearLCD();
main.backlightIdleMs = 0;
}
if (buttonCount == 1) {
main.displayMainMenu();
}
if (buttonCount == 2) {
main.menuWizard();
buttonCount = 1;
}
*/
main.printLCD();
};
Also, in the loop portion, I've commented the part of code that is intended to run, and I'm running a function that tests to see if I've successfully entered the loop by printing "test" on screen.
I'm using a Mega for this.
LED::LED()
{
InitTimersSafe();
pinMode(LCD_BACKLIGHT, OUTPUT);
lcd.begin(16, 2);
digitalWrite(LCD_BACKLIGHT, HIGH);
lcd.print("sEx LED, V1");
clearLCD();
delay(5000);
analogWrite(LCD_BACKLIGHT, BACKLIGHT_DIM);
You have to understand that this constructor is running when the object is created and that is probably before init() is run from main. So the hardware isn't ready at that point and pinMode and digitalWrite and stuff isn't going to work. The lcd code can't really work there and I bet that is the part that is hanging things.
A constructor should only do things like initialize variables. Any code that relies on the hardware should go into a begin() or init() or whatever method that you can call from setup once it is safe to do those things. The Serial object is a great example of another class that has to do this.

Arduino-4X4 matrix keypad with I/O shift register

I need help. I have done some research and my little understanding of keypad scanning is that the ShiftIn value of Input Column should return zero (0) when a keypad button is pressed. Mine is only returning 255 (or 11111111) in BIN. All I need is to track the zero value when a key is pressed and then scan the keys matrix to display the pressed key. I will appreciate any help. I have added my code and schematic.
]1
const int kbdRows = 4;
const int kbdCols = 4;
int LatchIn = 2; //165 pin1
int ClockPin = 3; // 595 pin11 & 165 pin2
int DataIn = 4; //165 pin9
int LatchOut = 5; // 595 pin12
int DataOut = 6; //595 pin14
int led = 7;
int PinState = 0;
char keys[kbdRows][kbdCols] = {
{ '1','2','3','4' },
{ '5','6','7','8' },
{ '9','0','A','B' },
{ 'C','D','E','F' }
};
byte KeyIsDown() {
int row;
int col;
int rowBits;
int colBits;
rowBits = 0X10;
for (row = 0; row < kbdRows; row++) {
digitalWrite(ClockPin, LOW);
digitalWrite(LatchOut, LOW);
shiftOut(DataOut, ClockPin, LSBFIRST, rowBits);
digitalWrite(LatchOut, HIGH);
delay(5);
digitalWrite(ClockPin, HIGH);
digitalWrite(LatchIn, LOW);
delay(5);
digitalWrite(LatchIn, HIGH);
colBits = shiftIn(DataIn, ClockPin, LSBFIRST);
for (col = 0; col < kbdCols; col++) {
if (colBits==0) {
// not sure what condition to put here
byte keypressed = keys[kbdRows][kbdCols]; here
// I know this is the right stuff to return here
}
return colBits;
colBits = colBits >> 1;
}
rowBits = rowBits << 1;
}
}
void setup() {
pinMode(ClockPin, OUTPUT);
pinMode(DataOut, OUTPUT);
pinMode(DataIn, INPUT_PULLUP);
pinMode(LatchOut, OUTPUT);
pinMode(LatchIn, OUTPUT);
digitalWrite(LatchOut, HIGH);
digitalWrite(LatchIn, HIGH);
Serial.begin(9600);
digitalWrite(led, HIGH);
}
void loop() {
byte retColBit = KeyIsDown();
Serial.print("ColBit: ");
Serial.println(retColBit,BIN);
delay(500);
PinState = digitalRead(DataOut);
Serial.print("DataOut: ");
Serial.println(PinState,BIN);
delay(500);
}

using Ultrasonic sensor to find obstecles Arduino

Am trying to make a smart cane for blind ppl using 2 ultrasonic sensors
to detect obstacles, and use a buzzer and a flat vibrating motor as a feedback when an obstacle is detected, where the flat motor should be ON when an obstacle
between 1m - 3m is detected, and the buzzer when it's less than 1m.
now recently i used the NewPing library which solved some of the problems but
the code doesn't do exactly what i want, instead it triggers both the buzzer and motor together when object detected, i'd appreciate it if anyone could help.
#include <NewPing.h>
const int trigPin = 8;
const int trigPin1 = 13;
const int echoPin = 9;
const int echoPin1 = 12;
const int buzzer = 5;
const int motor = 3;
NewPing sonar1(trigPin,echoPin,maxout);
NewPing sonar2(trigPin1,echoPin1,maxout);
// defines variables
long duration;
long duration1;
int distance;
int distance1;
void setup() {
pinMode(buzzer, OUTPUT);
pinMode(motor, OUTPUT);
Serial.begin(9600);
}
void loop() {
distance = sonar1.ping_cm();
distance1 = sonar2.ping_cm();
if (distance > 100 || distance1 > 100) {
digitalWrite(buzzer,LOW);
digitalWrite(motor,HIGH);
}
else if (distance <= 100 || distance1 <= 100) {
digitalWrite(buzzer,HIGH);
digitalWrite(motor,LOW);
}
Serial.print("Distance1: ");
Serial.println(distance);
Serial.print("Distance2: ");
Serial.println(distance1);
}
this is the ultrasonic pins:
first sensor (Vcc = 5V, trig = 8, echo = 9, GND = GND)
second sensor(Vcc = 5V, trig = 13 , echo = 12 , GND = GND)
and this is the buzzer and motor pins:
buzzer = 5 , GND
motor = 3 , GND
Separate the logic for the motor and the buzzer:
if (distance >= 100 && distance <= 300) {
// Motor on
digitalWrite(motor, HIGH);
}
else {
// Motor off
digitalWrite(motor, LOW);
}
if (distance1 < 100) {
// Buzzer on
digitalWrite(buzzer, HIGH);
}
else {
// Buzzer off
digitalWrite(buzzer, LOW);
}

Resources