I have an arduino with 3 sensors connected and need to send the information I'm getting from the said sensors to another arduino and have it displayed on a connected lcd. I tried to go about this by changing the float values I'm getting into a string, sending the string to the other arduino and displaying that on the lcd. But when I try to execute this, I get an error saying :
" In function 'void receiveEvent(int)':
16:24: error: incompatible types in assignment of int to char [7] "
#include <Wire.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
int sensePin = A0;
int sensorInput;
int lightPin = A1;
int lightInput;
int gasPin = A2;
int gasInput;
int buzzer = 13;
int b_state = 3;
float temp;
float light;
char t_buffer[7];
int state = 0;
void setup()
{
Wire.begin();
pinMode(A0, INPUT);
pinMode(A1,INPUT);
pinMode(buzzer, OUTPUT);
pinMode(A2, INPUT);
pinMode(buzzer, OUTPUT);
pinMode(b_state, INPUT_PULLUP);
Serial.begin(9600);
lcd.begin(16, 2);
attachInterrupt(digitalPinToInterrupt(3), buttons, FALLING);
}
void loop()
{
gasInput = analogRead(gasPin);
sensorInput = analogRead(sensePin);
lightInput = analogRead(lightPin);
temp = (float)sensorInput / 1024;
temp = temp * 5;
temp = temp - 0.498;
temp = temp * 100;
light = ((float)lightInput - 26) / 8.97;
dtostrf(temp, 6, 2, t_buffer);
Serial.print("Current Temperature: ");
Serial.println(temp);
Serial.print("Current Light: ");
Serial.println(light);
Serial.print("Gas (conc.?): ");
Serial.println(gasInput);
Wire.beginTransmission(9);
Wire.write(t_buffer, 7);
Wire.endTransmission();
delay(100);
if (state == 0){
lcd.setCursor(0, 0);
lcd.print("Temp (C): ");
lcd.setCursor(0,1);
lcd.print(t_buffer);
}
else {
lcd.setCursor(0,0);
lcd.print("Light Intensity: ");
lcd.setCursor (0,1);
lcd.print(light);
}
if (gasInput > 800)
digitalWrite(buzzer, HIGH);
else
digitalWrite(buzzer, LOW);
}
void buttons()
{
lcd.clear();
state = !state;
}
#include <Wire.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
float temp;
char t_buffer[7];
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
Wire.begin(9);
Wire.onReceive(receiveEvent);
}
void receiveEvent(int bytes) {
t_buffer = Wire.read();
//temp = t_buffer.toFloat();
}
void loop() {
lcd.setCursor(0, 0);
lcd.print("Temp (C): ");
lcd.setCursor(0,1);
lcd.print(t_buffer);
}
Also I have 2 separate float values that I need to send and I'm thinking I could time the transmissions properly and send them both one after the other. Is this a good way of doing this or is there an alternative way?
The circuit
This may not be a direct answer to your question but it may help you figure it out.
t_buffer is a pointer, while t_buffer[0] is the first character in your buffer. The Wire.read returns a char and not a pointer.
If the explanation above does not make sense you may want to read on arrays.
Having said that, since you main loop is almost empty you can use the suggestion by Juraj and use Wire.readBytes(t_buffer , bytes) this way you do not have to worry about indexing through the buffer.
I would strongly suggest that you put text data in t_buffer and test your application before trying to send a float.
Related
I am building a hx711-based weight scale that displays the measured weight on an LCD, along with the weight the LCD shows a "max weight" If weight>max weight the buzzer will buzz. I have written code to perform these functions but, the weight always goes to zero no matter what and I cant set the max weight. I will include a schematic and the code here:
https://imgur.com/wMFoVMB
#include "HX711.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
int IN1 = A0;
int IN2 = A1;
int over_val;
int data;
int g_weight;
int Weight;
const int buzzer = 13;
void setup()
{
pinMode(buzzer, OUTPUT);
lcd.init();
lcd.clear();
lcd.backlight();
pinMode(IN1, INPUT);
pinMode(IN2, INPUT);
Init_Hx711();
Serial.begin(9600);
Serial.print("Ready!\n");
Get_Maopi();
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Harry Brass ");
lcd.setCursor(0, 1);
lcd.print(" Gus Creech ");
delay(1000);
lcd.clear();
}
void loop()
{
Weight = Get_Weight();
g_weight = Weight - data;
lcd.setCursor(0, 0);
lcd.print("Weight:");
lcd.print(g_weight);
lcd.print("g ");
if (digitalRead(IN2) == LOW) {data = Weight;}
if (digitalRead(IN1) == LOW) {over_val = g_weight;
}
if (g_weight <= over_val)
{
lcd.setCursor ( 0, 1 );
lcd.print("Max Weight:");
lcd.print(over_val);
lcd.print("g ");
digitalWrite(buzzer, LOW);
}
else if (g_weight > over_val)
{
Serial.println("overload");
lcd.setCursor ( 0, 1 );
lcd.print("...OverLoad!!...");
digitalWrite(buzzer, HIGH);
}
delay(50);
}
I would start from checking the physical connections and trying to run a simple code like this: https://www.instructables.com/Arduino-Scale-With-5kg-Load-Cell-and-HX711-Amplifi/ .
Just to make sure everything is working fine.
I am an aeronautical student, new to the coding environment.
I'm currently working on a GPS neo 6m module with Arduino mega 2560, where I wanted to save the current location upon pressing the push button. Which function is to be used to save the location by pressing the push button.
Here is what I have done so far. Any help would be much appreciated. Thanks in advance.
#include <SoftwareSerial.h>
// The TinyGPS++ object
TinyGPSPlus gps;
static const int RXPin = 4, TXPin = 3; //gps module connections
static const uint32_t GPSBaud = 9600;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
const int PUSH_BUTTON = 2;
void setup(){
pinMode(PUSH_BUTTON, INPUT_PULLUP); //push button input
Serial.begin(9600);
ss.begin(GPSBaud);
}
void loop(){
unsigned char i;
static const double homeLat = 12.334455, homeLon = 05.112233;
while (ss.available() > 0){
gps.encode(ss.read());
if (gps.location.isUpdated()){
Serial.print("Latitude= ");
Serial.print(gps.location.lat(), 6);
Serial.print(" Longitude= ");
Serial.println(gps.location.lng(), 6);
}
status = digitalRead(PUSH_BUTTON);
if (status== HIGH){
*missing code/confused*
}
delay(1000);
}
}```
It is simple just store the values in 2 variables.
#include <SoftwareSerial.h>
// The TinyGPS++ object
TinyGPSPlus gps;
static const int RXPin = 4, TXPin = 3; //gps module connections
static const uint32_t GPSBaud = 9600;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
const int PUSH_BUTTON = 2;
double save_lat, save_lang;
void setup(){
pinMode(PUSH_BUTTON, INPUT_PULLUP); //push button input
Serial.begin(9600);
ss.begin(GPSBaud);
}
void loop(){
unsigned char i;
static const double homeLat = 12.334455, homeLon = 05.112233;
while (ss.available() > 0){
gps.encode(ss.read());
if (gps.location.isUpdated()){
Serial.print("Latitude= ");
Serial.print(gps.location.lat(), 6);
Serial.print(" Longitude= ");
Serial.println(gps.location.lng(), 6);
}
status = digitalRead(PUSH_BUTTON);
if (status== HIGH){
if (gps.location.isUpdated()){
save_lat = gps.location.lat();
save_lang = gps.location.lng();
}
}
delay(1000);
}
}
When switching between states, the lines get jumbled and the characters get mixed up. Nothing I've seen online helps and example code in the library works just fine. The main issue I think comes from when the LCD is wiped clean, but then I don't know where it should be wiped. I've moved it from loop() to the cases multiple times, and delays don't help.
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
#include "RTClib.h"
RTC_DS1307 rtc;
const int hourButton = 2; // Interrupt Pin 0 -- TOP
const int minuteButton = 3; // Interrupt Pin 1 -- 2nd
const int displayStateButton = 18; // Interrupt Pin 5 -- 3rd
const int alarmButton = 19; // Interrupt Pin 4 -- BOTTOM
int buttonState = LOW;
int redPin = 4;
int greenPin = 5; // RGB LED Pins
int bluePin = 6;
int alarmPin = 13; // Alarm Pin
enum DeviceDisplayState {CLOCK, ALARM, DATE, YEAR}; // All different states
DeviceDisplayState displayState = CLOCK; // Initially in Clock State
#ifdef DEBOUNCE
long lastDebounceTime = 0;
long debounceDelay = 60;
#endif
void setup() {
lcd.begin(16, 2);
Serial.begin(57600);
// Set the time:: //
const int hourInit = 1;
const int minuteInit = 2;
const int secondInit = 1;
const int dayInit = 3;
const int monthInit = 4;
const int yearInit = 2020;
rtc.adjust(DateTime(yearInit, monthInit, dayInit, hourInit , minuteInit, secondInit));
pinMode(hourButton, INPUT_PULLUP);
pinMode(minuteButton, INPUT_PULLUP);
pinMode(displayStateButton, INPUT_PULLUP);
attachInterrupt(0, increaseHour, FALLING);
attachInterrupt(1, increaseMinute, FALLING);
attachInterrupt(5, SwitchToNextDisplayState, FALLING);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(alarmPin, OUTPUT);
SwitchToClockState();
};
void RGB_color(int red_light_value, int green_light_value, int blue_light_value)
{
analogWrite(redPin, red_light_value);
analogWrite(greenPin, green_light_value);
analogWrite(bluePin, blue_light_value);
}
void increaseHour()
{
DateTime dt = rtc.now();
Serial.print("Previous Time: " + dt.hour());
if (dt.hour() < 23)
{
TimeSpan ts(3600);
dt = dt + ts;
}
else // do not roll over the day by upping the hour, go back to zero hours
{
TimeSpan ts(3600 * 23);
dt = dt - ts;
}
Serial.print("Changed Time: " + dt.hour());
Serial.println();
rtc.adjust(dt);
}
void increaseMinute()
{
DateTime dt = rtc.now();
if (dt.minute() < 59)
{
TimeSpan ts(60);
dt = dt + ts;
}
else // Don't roll over the minutes into the hours
{
TimeSpan ts(60 * 59);
dt = dt - ts;
}
rtc.adjust(dt);
}
void SwitchToClockState()
{
displayState = CLOCK;
RGB_color(255, 0, 0);
}
void SwitchToAlarmState()
{
displayState = ALARM;
RGB_color(255, 125, 0);
}
void SwitchToDateState()
{
displayState = DATE;
RGB_color(0, 255, 0);
}
void SwitchToYearState()
{
displayState = YEAR;
RGB_color(0, 0, 255);
}
void SwitchToNextDisplayState()
{
switch (displayState) {
case CLOCK:
SwitchToAlarmState();
Serial.print("Switching to Alarm State...");
Serial.println();
lcd.clear();
break;
case ALARM:
SwitchToDateState();
Serial.print("Switching to Date State...");
Serial.println();
lcd.clear();
break;
case DATE:
SwitchToYearState();
Serial.print("Switching to Year State...");
Serial.println();
lcd.clear();
break;
case YEAR:
SwitchToClockState();
Serial.print("Switching to Clock State...");
Serial.println();
lcd.clear();
break;
default:
// assert()
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
break;
}
}
String WithLeadingZeros(int number)
{
if (number < 10)
{
return "0" + String(number);
}
else
{
return String(number);
}
}
void loop() {
DateTime now = rtc.now();
int yearInt = now.year();
int monthInt = now.month();
int dayInt = now.day();
int hourInt = now.hour();
int minuteInt = now.minute();
int secondInt = now.second();
switch (displayState) {
case CLOCK:
lcd.print("Robot Slave");
lcd.setCursor(0, 1);
lcd.print("Time> " + WithLeadingZeros(now.hour()) + ":" + WithLeadingZeros(now.minute()) + ":" + WithLeadingZeros(now.second()));
break;
case ALARM:
lcd.print("Robot Slave");
case DATE:
lcd.print("Robot Slave");
lcd.setCursor(0, 1);
lcd.print("Date> " + WithLeadingZeros(now.month()) + " - " + WithLeadingZeros(now.day()));
break;
//case YEAR:
lcd.print("Robot Slave");
lcd.setCursor(0, 1);
lcd.print("Year> " + String(now.year()));
break;
}
}
You're creating nonsense instructions for your LCD if you execute commands in an ISR while already executing instructions in your normal program.
Let's say the serial command to write letter A is "WRITEA" and the command for clearing the display is "CLEAR".
Now while sending the letter A to your display you push the button, your display will receive something like "WRCLEARTEB" which it cannot make sense of. Or maybe it receives "WRITECLEARA" and it will write C instead of A.
Please note that this is just to give you an idea what is going on. Of course the data sent to the display is different.
But you're creating a mess by interleaving commands.
Update your display in a loop and use ISRs only to update variables that are then used in the next frame. Clocks with second precision are usually updated once per second.
im doing a tachometer with arduino uno and this is my code:
int ledPin = 13;
volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void rpm2()
{
rpmcount++;
}
void setup()
{
lcd.begin(16, 2);
attachInterrupt(0, rpm2, FALLING);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
rpmcount = 0;
rpm = 0;
timeold = 0;
}
void loop()
{
delay(1000);
detachInterrupt(0);
rpm = 30*1000/(millis() -Timeold)*rpmcount;
timeold = millis();
rpmcount = 0;
lcd.clear();
lcd.print("RPM=");
lcd.print(rpm);
attachInterrupt(0, rpm2, FALLING);
}
When i turn on arduino e starts giving me random numbers on rpm and i have no idea why. Even if i remove the IR it keeps showing the random numbers
I am working on a robotic arm that has six servos which is being controlled by an arduino uno. The servos are analog servos from adafruit and they are special in the sense that you can get feedback from the servos, i.e their actual position after you told it where to go. What I am working on is trying to adapt this example code to include six servos instead of one. https://github.com/adafruit/Feedback-Servo-Record-and-Play/blob/master/servo_recordplay.ino
Here is my code so far and its errors
// Example code for recording and playing back servo motion with a
// analog feedback servo
// http://www.adafruit.com/products/1404
#include <Servo.h>
#include <EEPROM.h>
#define CALIB_MAX 512
#define CALIB_MIN 100
#define SAMPLE_DELAY 25 // in ms, 50ms seems good
uint8_t recordButtonPin = 12;
uint8_t playButtonPin = 7;
uint8_t servo1Pin = 9;
uint8_t servo2Pin = 10;
uint8_t servo1FeedbackPin = A0;
uint8_t servo2FeedbackPin = A1;
uint8_t servo3FeedbackPin = A2;
uint8_t servo4FeedbackPin = A3;
uint8_t servo5FeedbackPin = A4;
uint8_t servo6FeedbackPin = A5;
uint8_t ledPin = 13;
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
void setup() {
Serial.begin(9600);
pinMode(recordButtonPin, INPUT);
digitalWrite(recordButtonPin, HIGH);
pinMode(playButtonPin, INPUT);
digitalWrite(playButtonPin, HIGH);
pinMode(ledPin, OUTPUT);
Serial.println("Servo RecordPlay");
}
void loop() {
if (! digitalRead(recordButtonPin)) {
delay(10);
// wait for released
while (! digitalRead(recordButtonPin));
delay(20);
// OK released!
recordAllServos(servo1Pin, servo1FeedbackPin, recordButtonPin);
}
if (! digitalRead(playButtonPin)) {
delay(10);
// wait for released
while (! digitalRead(playButtonPin));
delay(20);
// OK released!
playAllServo(servo1Pin, playButtonPin);
}
}
void playAllServo(uint8_t servoPin, uint8_t buttonPin) {
uint16_t addr = 0;
Serial.println("Playing");
servo1.attach(servo1Pin);
while (digitalRead(buttonPin)) {
uint8_t x = EEPROM.read(addr);
Serial.print("Read EE: "); Serial.print(x);
if (x == 255) break;
// map to 0-180 degrees
x = map(x, 0, 254, 0, 180);
Serial.print(" -> "); Serial.println(x);
servo1.write(x);
delay(SAMPLE_DELAY);
addr++;
if (addr == 512) break;
}
Serial.println("Done");
servo1.detach();
delay(250);
}
void recordAllServos(uint8_t servoPin, uint8_t buttonPin) {
uint16_t addr = 0;
Serial.println("Recording");
digitalWrite(ledPin, HIGH);
pinMode(servo1FeedbackPin, INPUT);
pinMode(servo2FeedbackPin, INPUT);
pinMode(servo3FeedbackPin, INPUT);
pinMode(servo4FeedbackPin, INPUT);
pinMode(servo5FeedbackPin, INPUT);
pinMode(servo6FeedbackPin, INPUT);
while (digitalRead(buttonPin))
{
readServo(servo1FeedbackPin);
readServo(servo2FeedbackPin);
readServo(servo3FeedbackPin);
readServo(servo4FeedbackPin);
readServo(servo5FeedbackPin);
readServo(servo6FeedbackPin);
if (addr > 506) break;
delay(SAMPLE_DELAY);
}
if (addr != 1024) EEPROM.write(addr, 255);
digitalWrite(ledPin, LOW);
Serial.println("Done");
delay(250);
}
void readAllServo(uint8_t analogPin)
{
uint16_t a = analogRead(analogPin);
Serial.print("Read analog pin "); Serial.print(analogPin); Serial.print(": ");
Serial.print(a);
if (a < CALIB_MIN) a = CALIB_MIN;
if (a > CALIB_MAX) a = CALIB_MAX;
a = map(a, CALIB_MIN, CALIB_MAX, 0, 254);
Serial.print(" -> "); Serial.println(a);
EEPROM.write(addr, a);
addr++;
}
The errors that I am getting from the arduino ide are
Teachable_Arm_Mark.cpp: In function 'void loop()':
Teachable_Arm_Mark:10: error: too many arguments to function 'void recordAllServos(uint8_t, uint8_t)'
Teachable_Arm_Mark:49: error: at this point in file
Teachable_Arm_Mark.cpp: In function 'void recordAllServos(uint8_t, uint8_t)':
Teachable_Arm_Mark:100: error: 'readServo' was not declared in this scope
Teachable_Arm_Mark.cpp: In function 'void readAllServo(uint8_t)':
Teachable_Arm_Mark:127: error: 'addr' was not declared in this scope
Any help much appreciated
Thanks
In void loop you have
recordAllServos(servo1Pin, servo1FeedbackPin, recordButtonPin);
but recordAllServos is declared as
void recordAllServos(uint8_t servoPin, uint8_t buttonPin)
Hence too many arguments 3 vs 2...