Error While Printing on I2C OLED Display in Arduino - arduino

#define OLED_RESET -1
Adafruit_SSD1306 display(OLED_RESET);
char buff[10]="hola";
char buff2[10]="";
int cnt=0;
int b=0;
int alpha=1;
void setup()
{
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextColor(WHITE);
Serial.begin(9600);
}
void loop()
{
while (Serial.available()) {
char a = Serial.read();
buff[cnt++] = a;
alpha=1;
}
if(alpha==1){
display.clearDisplay();
display.setCursor(0,0);
display.setTextSize(1);
display.println(buff);
display.display();
cnt=0;
alpha=0;
}
}
it prints first incoming string at place where i wat but when it receives second string it shifts to new line mean changes y position and after that it does not print any thing on display. Could any one can tell me the error i have made here.

The string you are building from the received characters isn't null-terminated when you print it. Add
buff[cnt++] = '\0';
before calling println.

this code does the same thing as yours but with strings(I thing it is more useful than char arrays) Don't forget to replace "MaxLength" in line 15 with your own number
#define OLED_RESET -1
Adafruit_SSD1306 display(OLED_RESET);
String input;
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextColor(WHITE);
Serial.begin(9600);
}
void loop() {
if(Serial.available() > 0){ //if input available
input = Serial.readString(); //Serial input to string
if(input.length() > MaxLength) input = ""; // check if string isn't too long, replace 20 with your value
display.clearDisplay();
display.setCursor(0,0);
display.setTextSize(1);
display.print(input); //I removed "ln" from println to not send \n at end of string
display.display();
}
}
I hope this will work

Related

LCD Arduino not displaying correctly

My problem is when I input the string in the serial monitor it shows like this:
LCD Arduino Error
The setCursor dont work and also there is another weird character created before the actual output.
This is my sample code:
void setup() {
lcd.begin(16, 2);
Serial.begin(9600);
lcd.print("hello, world!");
}
void loop() {
String readString;
String Q;
while (Serial.available()) {
delay(1);
if (Serial.available()>0) {
char c = Serial.read();
if(isControl(c)){
break;
}
readString += c;
}
}
Q = readString;
if (Q == "1"){
lcd.setCursor(0,1);
lcd.print("Hello");
}
if (Q == "2"){
lcd.setCursor(0,1);
lcd.print("World");
}
}
First of all you should understand the LCD lib functions. To set the cursorto theFirst row you need
lcd.setCursor(0,0); // row index starts with 0
if you only set the cursor back without clearing the screen there might be weird chars,sodo a
lcd.clear(); //clears the whole screen
OR define an empty String:
String lineClear =" "; // should be 16 spaces for a 16x2 display
and do as a clearing sequence (e.g. for the top line)
lcd.setCursor(0,0);
lcd.print(lineClear);
lcd.print("Hello");
Remember the syntax is
lcd.setCursor(col, row)
// index for 16x2 is col 0-15,row 0-1
// index for 20x4 is col 0-19,row 0-3
and in setup alwas do a
lcd.clear();
after initializing the lcd, to remove possible artefacts from the buffer

Why Arduino int can't count over 14464?

I got some problem about reading from MPU6050 and then write to SD card.
Actually I could successfully do the read-and-write, but I found Arduino UNO can't count over 14464!?
I set every line of my data that is:
count, time(millis()), ax, ay, az, gx, gy, gz
It could record the data right till count to 14464 (I) and it will end the loop automated.
It really bothers me... and it seems no one face this problem before.
Here is my code:
#include "I2Cdev.h"
#include "MPU6050.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
MPU6050 accelgyro;
//SD card here
#include <SPI.h>
#include <SD.h>
File myFile;
//////////Global Variable Here//////////
int16_t ax, ay, az;
int16_t gx, gy, gz;
int count = 1;
//set sec & count_limit
int set_time = 1000 * 60;
int count_limit = 80000;
int BTN = 7;
// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO
//Set LED
#define R_PIN 8
#define G_PIN 9
bool blinkState_R = false;
bool blinkState_G = false;
void setup() {
// configure Arduino LED for
pinMode(R_PIN, OUTPUT);
pinMode(G_PIN, OUTPUT);
pinMode(BTN, INPUT);
digitalWrite(G_PIN, HIGH);
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
// initialize serial communication
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
// it's really up to you depending on your project)
Serial.begin(38400);
// initialize device
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
// use the code below to change accel/gyro offset values
accelgyro.setXGyroOffset(59);
accelgyro.setYGyroOffset(42);
accelgyro.setZGyroOffset(-8);
accelgyro.setXAccelOffset(1359);
accelgyro.setYAccelOffset(-1620);
accelgyro.setZAccelOffset(1917);
/////////////////////////////////////////////////////////////////////
//SD card Initailize
/////////////////////////////////////////////////////////////////////
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
digitalWrite(R_PIN, HIGH);
return;
}
Serial.println("initialization done.");
digitalWrite(R_PIN, LOW);
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
// open a new file and immediately close it:
Serial.println("Creating example.txt...");
myFile = SD.open("example.txt", FILE_WRITE);
myFile.close();
// Check to see if the file exists:
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
// delete the file:
Serial.println("Removing example.txt...");
SD.remove("example.txt");
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
delay(3000);
////////////////////////////////////////////////////////////////////////////////
//SD END
////////////////////////////////////////////////////////////////////////////////
digitalWrite(G_PIN, LOW);
}
void loop() {
// read raw accel/gyro measurements from device
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
blinkState_R = !blinkState_R;
digitalWrite(R_PIN, blinkState_R);
// these methods (and a few others) are also available
//accelgyro.getAcceleration(&ax, &ay, &az);
//accelgyro.getRotation(&gx, &gy, &gz);
////////////////////////////////////////////
// Write to SD Card
///////////////////////////////////////////
// write data to file
if(count <= count_limit ){
myFile = SD.open("IMU_LOG.txt", FILE_WRITE);
Serial.print(count);Serial.print("\t"); myFile.print(count); myFile.print("\t");
Serial.print(millis()); Serial.print("\t"); myFile.print(millis()); myFile.print("\t");
Serial.print(ax); Serial.print("\t"); myFile.print(ax); myFile.print("\t");
Serial.print(ay); Serial.print("\t"); myFile.print(ay); myFile.print("\t");
Serial.print(az); Serial.print("\t"); myFile.print(az); myFile.print("\t");
Serial.print(gx); Serial.print("\t"); myFile.print(gx); myFile.print("\t");
Serial.print(gy); Serial.print("\t"); myFile.print(gy); myFile.print("\t");
Serial.print(gz); Serial.print("\n"); myFile.print(gz); myFile.print("\n");
myFile.close();
delay(5);
blinkState_G = !blinkState_G;
digitalWrite(G_PIN, blinkState_G);
}else{
while(1){
Serial.print("Process done.\n");
digitalWrite(G_PIN, OUTPUT);
delay(2000);
}
count= count + 1 ;
}
You should be getting a compiler warning here.
int count_limit = 80000;
The maximum value of int on your platform is 32,767. When you set an int to something larger, the behavior is undefined, which is bad news because it means that your program is incorrect.
In this particular case, you might notice that 80000 = 14464 + 216, which explains why it stopped at 14464, if int is 16 bits long.
You will need to use long if you want to count higher than 65,535.
long count_limit = 80000L;
long count = 1;

Sending IR signal from Arduino to F&D speakers

I am using below code to send an IR signal to my speaker but they don't respond.
#include <IRremote.h>
IRsend irsend;
const int buttonPin = 8; // the number of the pushbutton pin
//const int ledPin = 3;
int buttonState = 0; // variable for reading the pushbutton status
void setup()
{
// pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(7,HIGH);
irsend.sendNEC(0x1FE08F7,32);
}else{
digitalWrite(7,LOW);
}
}
IR Reciever on my other Arduino receives signal but also they vary sometime it shows UNKNOWN and sometime NEC. I am using below code:
#include <IRremote.h>
const int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
irrecv.blink13(true);
}
void loop() {
if (irrecv.decode(&results)) {
if (results.decode_type == NEC) {
Serial.print("NEC: ");
} else if (results.decode_type == SONY) {
Serial.print("SONY: ");
} else if (results.decode_type == RC5) {
Serial.print("RC5: ");
} else if (results.decode_type == RC6) {
Serial.print("RC6: ");
} else if (results.decode_type == UNKNOWN) {
Serial.print("UNKNOWN: ");
}
Serial.println(results.value, HEX);
Serial.println(results.value);
irrecv.resume(); // Receive the next value
}
}
The NEC code that I recieved is correct but on that code speaker does not respond. I double checked the HEX code with the remote that came along with speaker but nothing seem to work.
I think that you could have problem with the HEX literal.
From Arduino API:
By default, an integer constant is treated as an int with the attendant limitations in values. To specify an integer constant with another data type, follow it with:
a 'u' or 'U' to force the constant into an unsigned data format. Example: 33u
a 'l' or 'L' to force the constant into a long data format. Example: 100000L
a 'ul' or 'UL' to force the constant into an unsigned long constant. Example: 32767ul
And from GitHub:
void sendNEC (unsigned long data, int nbits) ;
So, try:
irsend.sendNEC(0x01FE08F7UL,32);

Serial communication on Arduino

I have an assignment for school where I need to turn on a led with the serial message #ON%, and turn the led off with #OFF%. The # and % are the identifiers for the correct string. So I made this code:
(bericht means message in Dutch)
String readString = "";
int recievedCharacter;
String bericht = "";
int ledPin = 6;
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
pinMode(ledPin, OUTPUT);
}
void loop()
{
while (Serial.available() > 0)
{
delay(4);
char readChar = (char) Serial.read(); // 'Convert' to needed type
bericht += + readChar; // concatenate char to message
}
if(bericht.startsWith("#"))
{
if(bericht == "#ON%")
{
Serial.println(bericht);
Serial.println("goed");
digitalWrite(ledPin, HIGH);
//message = "";
}
if(bericht == "#OFF%")
{
Serial.println("goed");
digitalWrite(ledPin, LOW);
//message = "";
}
}
}
The problem is the program will never get into the if(bericht == "#ON%") section...
Sorry if this is a silly question but with a lot of googling I just can't figure it out...
The problem is here:
bericht += + readChar; // concatenate char to message // XXX '+ char' => int
this actually appends an integer to the message. Remove the +:
bericht += readChar; // concatenate char to message // Goed!

How to transmit a String on Arduino?

I want 2 Arduinos Leonardo to communicate, send a string for instance, so I have to use Serial1 to communicate via RS232 on pins 0 (RX) and 1 (TX).
I need to write binary data in that pins, the problem is how can I send a String using Serial1.write. Serial1.print works without errors but I think it does not do what I want. Any suggestion?
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
while (!Serial); // while not open, do nothing. Needed for Leonardo only
}
void loop() {
String outMessage = ""; // String to hold input
while (Serial.available() > 0) { // check if at least one char is available
char inChar = Serial.read();
outMessage.concat(inChar); // add Chars to outMessage (concatenate)
}
if (outMessage != "") {
Serial.println("Sent: " + outMessage); // see in Serial Monitor
Serial1.write(outMessage); // Send to the other Arduino
}
}
this line Serial1.write(outMessage); is giving me the error
"no matching function for call to 'HardwareSerial::write(String&)'"
You're using the String object(Wiring/C++). The function is using C strings: Serial.write(char*). To turn it into a C string, you use the toCharArray() method.
char* cString = (char*) malloc(sizeof(char)*(outMessage.length() + 1);
outMessage.stoCharArray(cString, outMessage.length() + 1);
Serial1.write(cString);
If we do not allocate the memory for our C string with malloc, we will get a fault. The following code WILL crash.
void setup() {
Serial.begin(9600);
String myString = "This is some new text";
char* buf;
Serial.println("Using toCharArray");
myString.toCharArray(buf, myString.length()+1); // **CRASH** buf is not allocated!
Serial.println(buf);
}
void loop() {
// put your main code here, to run repeatedly:
}
In the Serial Monitor the only message we will get is: Using toCharArray. At that point execution stops. Now if we correct the problem and use malloc() to allocate memory for our buffer and also use free() when done....
void setup() {
Serial.begin(9600);
String myString = "This is some new text";
char* buf = (char*) malloc(sizeof(char)*myString.length()+1);
Serial.println("Using toCharArray");
myString.toCharArray(buf, myString.length()+1);
Serial.println(buf);
Serial.println("Freeing the memory");
free(buf);
Serial.println("No leaking!");
}
void loop() {
// put your main code here, to run repeatedly:
}
The output we see in the Serial Monitor is:
Using toCharArray
This is some new text
Freeing the memory
No leaking!
Use toCharArry(), write() uses char*, not string, here is what i mean:
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
while (!Serial);
}
void loop() {
String outMessage = "";
while (Serial.available() > 0) {
char inChar = Serial.read();
outMessage.concat(inChar);
}
if (outMessage != "") {
Serial.println("Sent: " + outMessage);
char* CharString; //
outMessage.toCharArray(cString, outMessage.length()) // My Changes Are Here
Serial1.write(CharString); //
}
}

Resources