I am trying to display the readings from a laser rangefinder onto an LCD. I am able to display the serial on it along with "cm" but it keeps adding two symbols that appear to be Chinese. This is my first project using Arduino, can someone help me?
#include <LiquidCrystal.h>
/**
* LIDARLite I2C Example
* Author: Garmin
* Modified by: Shawn Hymel (SparkFun Electronics)
* Date: June 29, 2017
*
* Read distance from LIDAR-Lite v3 over I2C
*
* See the Operation Manual for wiring diagrams and more information:
* http://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf
*/
#include <Wire.h>
#include <LIDARLite.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Globals
LIDARLite lidarLite;
int cal_cnt = 0;
void setup()
{
Serial.begin(9600); // Initialize serial connection to display distance readings
lidarLite.begin(0, true); // Set configuration to default and I2C to 400 kHz
lidarLite.configure(0); // Change this number to try out alternate configurations
lcd.begin(16, 2);
// initialize the serial communications:
}
void loop()
{
int dist;
// At the beginning of every 100 readings,
// take a measurement with receiver bias correction
if ( cal_cnt == 0 ) {
dist = lidarLite.distance(); // With bias correction
} else {
dist = lidarLite.distance(false); // Without bias correction
}
// Increment reading counter
cal_cnt++;
cal_cnt = cal_cnt % 100;
// Display distance
Serial.print(dist);
Serial.println(" cm");
delay(100);
// when characters arrive over the serial port...
if (Serial.available()) {
// wait a bit for the entire message to arrive
delay(100);
// clear the screen
lcd.clear();
// read all the available characters
while (Serial.available() > 0) {
// display each character to the LCD
lcd.write(Serial.read());
}
}
delay(100);
lcd.clear();
lcd.println(dist);
lcd.println(" cm");
}
It should just display (measurement) cm on the LCD.
Instead I keep getting 218-- cm--, -- being the two Chinese symbols.
It seems to be showing the carriage return and newline characters.
Replace println with print.
Related
I am trying to get the following code running on an Arduino Leonardo (because it has native usb) and it doesn't work. It doesn't even print anything to the serial monitor. When I try it with an Arduino Nano, everything works fine. I have considered whether maybe it is because the softwareSerial library doesn't work with Leonardo, but I couldn't find any information about it online. Anybody has any idea why it doesn't work?
/*****************************
RFID-powered lockbox
Written by: acavis, 3/31/2015
Modified: Ho YUN "Bobby" Chan # SparkFun Electronics Inc., 11/10/2017
Inspired by & partially adapted from
http://bildr.org/2011/02/rfid-arduino/
Description: This sketch will move a servo when
a trusted tag is read with the
ID-12/ID-20 RFID module
----------HARDWARE HOOKUP----------
PINOUT FOR SERVO MOTOR
Servo Motor ----- Arduino
GND GND
Vcc 5V
SIG D9
PINOUT FOR SPARKFUN RFID USB READER
Arduino ----- RFID module
5V VCC
GND GND
D2 TX
PINOUT FOR SPARKFUN RFID BREAKOUT BOARD
Arduino ----- RFID module
5V VCC
GND GND
GND FORM
D2 D0
Optional: If using the breakout, you can also
put an LED & 330 ohm resistor between
the RFID module's READ pin and GND for
a "card successfully read" indication.
Note: Make sure to GND the FORM pin to enable the ASCII output format.
--------------------------------------------------
******************************/
#include <SoftwareSerial.h>
#include <Servo.h>
// Choose two pins for SoftwareSerial
SoftwareSerial rSerial(2, 3); // RX, TX
// Make a servo object
Servo lockServo;
// Pick a PWM pin to put the servo on
const int servoPin = 9;
// For SparkFun's tags, we will receive 16 bytes on every
// tag read, but throw four away. The 13th space will always
// be 0, since proper strings in Arduino end with 0
// These constants hold the total tag length (tagLen) and
// the length of the part we want to keep (idLen),
// plus the total number of tags we want to check against (kTags)
const int tagLen = 16;
const int idLen = 13;
const int kTags = 4;
// Put your known tags here!
char knownTags[kTags][idLen] = {
"111111111111",
"444444444444",
"555555555555",
"7A005B0FF8D6"
};
// Empty array to hold a freshly scanned tag
char newTag[idLen];
void setup() {
// Starts the hardware and software serial ports
Serial.begin(9600);
rSerial.begin(9600);
// Attaches the servo to the pin
lockServo.attach(servoPin);
// Put servo in locked position
// Note: Value may need to be adjusted
// depending on servo motor
lockServo.write(0);
}
void loop() {
// Counter for the newTag array
int i = 0;
// Variable to hold each byte read from the serial buffer
int readByte;
// Flag so we know when a tag is over
boolean tag = false;
// This makes sure the whole tag is in the serial buffer before
// reading, the Arduino can read faster than the ID module can deliver!
if (rSerial.available() == tagLen) {
tag = true;
}
if (tag == true) {
while (rSerial.available()) {
// Take each byte out of the serial buffer, one at a time
readByte = rSerial.read();
/* This will skip the first byte (2, STX, start of text) and the last three,
ASCII 13, CR/carriage return, ASCII 10, LF/linefeed, and ASCII 3, ETX/end of
text, leaving only the unique part of the tag string. It puts the byte into
the first space in the array, then steps ahead one spot */
if (readByte != 2 && readByte!= 13 && readByte != 10 && readByte != 3) {
newTag[i] = readByte;
i++;
}
// If we see ASCII 3, ETX, the tag is over
if (readByte == 3) {
tag = false;
}
}
}
// don't do anything if the newTag array is full of zeroes
if (strlen(newTag)== 0) {
return;
}
else {
int total = 0;
for (int ct=0; ct < kTags; ct++){
total += checkTag(newTag, knownTags[ct]);
}
// If newTag matched any of the tags
// we checked against, total will be 1
if (total > 0) {
// Put the action of your choice here!
// I'm going to rotate the servo to symbolize unlocking the lockbox
Serial.println("Success!");
lockServo.write(180);
}
else {
// This prints out unknown cards so you can add them to your knownTags as needed
Serial.print("Unknown tag! ");
Serial.print(newTag);
Serial.println();
}
}
// Once newTag has been checked, fill it with zeroes
// to get ready for the next tag read
for (int c=0; c < idLen; c++) {
newTag[c] = 0;
}
}
// This function steps through both newTag and one of the known
// tags. If there is a mismatch anywhere in the tag, it will return 0,
// but if every character in the tag is the same, it returns 1
int checkTag(char nTag[], char oTag[]) {
for (int i = 0; i < idLen; i++) {
if (nTag[i] != oTag[i]) {
return 0;
}
}
return 1;
}
Code is from here: https://learn.sparkfun.com/tutorials/sparkfun-rfid-starter-kit-hookup-guide/all
From: https://docs.arduino.cc/learn/built-in-libraries/software-serial
Not all pins on the Mega and Mega 2560 boards support change
interrupts, so only the following can be used for RX: 10, 11, 12, 13,
14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12
(66), A13 (67), A14 (68), A15 (69). Not all pins on the Leonardo and
Micro boards support change interrupts, so only the following can be
used for RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
So this SoftwareSerial rSerial(2, 3); // RX, TX won't work.
Also Arduino Leonardo has two hardware serials. I don't see why you would use SoftwareSerial here.
first sorry for my bad english
I'm a student and I want to make a Stroboscope with Arduino for my school project
The frequency is variable between 10hz to 3000 hz and it changes using a rotary encoder
that when normally rotate the encoder 1 step frequency \pm 1hz and when rotate encoder when it pushed down frequency \pm 100hz
and Arduino make a PWM signal on pin 13 and it connect to a high power npn transistor and it turn on and off a 10 watt led
I code it using Encoder.h library by Paul Stoffregen and tone() function
but I have a PROBLEM
I code this program and upload it to Arduino Uno but it doesn't work IDK where is the problem
#include <Encoder.h>
#define ENCODER_PULSES_PER_STEP 1
int f = 10;
int direction;
Encoder myEnc(2, 3);
int t = 0;
void setup() {
pinMode(13, OUTPUT);
pinMode(4, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
direction = myEnc.read();
}
void loop() {
if (abs(direction) >= ENCODER_PULSES_PER_STEP) {
if (direction > 0) {
if (digitalRead(4) == 1) {
f++;
if (f >> 2500)f = 2500;
}
else {
f = f + 100;
if (f >> 2500)f = 2500;
}
} else {
if (digitalRead(4) == 1) {
f--;
if (f << 10)f = 10;
}
else {
f = f - 100;
}
}
myEnc.write(0);
}
tone(13, f);
}
When your program starts the function setup is executed once.
Then in an infinite loop the function loop is executed.
As you have direction = myEnc.read(); only in setup you'll only read the encoder once.
From the Encoder library's documentation:
/* Encoder Library - TwoKnobs Example
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/
#include <Encoder.h>
// Change these pin numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder knobLeft(5, 6);
Encoder knobRight(7, 8);
// avoid using pins with LEDs attached
void setup() {
Serial.begin(9600);
Serial.println("TwoKnobs Encoder Test:");
}
long positionLeft = -999;
long positionRight = -999;
void loop() {
long newLeft, newRight;
newLeft = knobLeft.read();
newRight = knobRight.read();
if (newLeft != positionLeft || newRight != positionRight) {
Serial.print("Left = ");
Serial.print(newLeft);
Serial.print(", Right = ");
Serial.print(newRight);
Serial.println();
positionLeft = newLeft;
positionRight = newRight;
}
// if a character is sent from the serial monitor,
// reset both back to zero.
if (Serial.available()) {
Serial.read();
Serial.println("Reset both knobs to zero");
knobLeft.write(0);
knobRight.write(0);
}
}
Notice the differences between your and their code.
Another more simple example from the GitHub repository to satisfy Juraj.
/* Encoder Library - Basic Example
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/
#include <Encoder.h>
// Change these two numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder myEnc(5, 6);
// avoid using pins with LEDs attached
void setup() {
Serial.begin(9600);
Serial.println("Basic Encoder Test:");
}
long oldPosition = -999;
void loop() {
long newPosition = myEnc.read();
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}
}
Also note that << is the binary left shift operator, not the less than operator < !
In if (f << 10)f = 10; you'll shift f 10 bits to the left. As this results in a number > 0, which is true, this condition will alway be met.
Same for >> which is the bitwise right shift operator, not greater then!
I'm using Tinkercad, and since it's my first time programming an LCD I just copied the procedure to connect the pins and make it work.
The thing is that it just lights up without displaying anything, I tried both wiring and unwiring the R/W pin but that doesn't work either, nothing will be displayed.
What did I miss? The other functions of the code works normally.
Image of the circuit:
This is the code:
#include <LiquidCrystal.h>
const int pin = 0; // analog pin
float celsius = 0, farhenheit =0; // temperature variables
float millivolts; //Millivolts from the sensor
int sensor;
const int G_LED = 13;
const int Y_LED = 12;
LiquidCrystal lcd(10, 9, 5, 4, 3, 2); // Building the LCD
void setup() {
lcd.begin(16,2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("C="); // "C=", "F=" and "mV" should be printed
lcd.setCursor(0, 1); // on the LCD in a column
lcd.print("F=");
lcd.setCursor(0, 2);
lcd.print("mV=");
pinMode(G_LED, OUTPUT);
pinMode(Y_LED, OUTPUT);
Serial.begin(9600);
}
void loop() {
sensor = analogRead(pin); // Reading the value from the LM35 sensor using the A0 ingress
millivolts = (sensor / 1023.0) * 5000; // Converting the value in a number that indicates the millivolts
celsius = ((sensor * 0.00488) - 0.5) / 0.01; // Celsius value (10 mV for each degree, 0°=500mV)
farhenheit = celsius * 1.8 + 32; // Fahrenheit value
lcd.setCursor(4, 2); // Set the cursor at the right of "mV="
lcd.print(millivolts); // Print the mV value
lcd.setCursor(4, 0); // Same here for °C and °F
lcd.print(celsius);
lcd.setCursor(4, 1);
Serial.print(farhenheit);
if (millivolts < 700) { // Green LED is on when the temperature is under or equal to 20°
// if (celsius < 20) { // Alternative
analogWrite(G_LED, 255);
analogWrite(Y_LED, 0); }
else {
analogWrite(G_LED, 0);
analogWrite(Y_LED, 255); // Yellow LED is on when the temperature is above of 20°C
}
delay(1000);
}
Fix - I could not find the error, but I suspect it was due to the strange layout of the connections. You also tried to set the cursor to line 3, but the LCD you were using did not have 3 lines, it was a 16x2 LCD.
What I Did - So what I did was I re-did the entire project, I linked up a new LCD, this time with a digital contrast so that it could be dynamically changed. I also made sure to include the sensor you used in your last project. Over-all the project is an Arduino controlling an LCD and outputting the temperature in Fahrenheit and millivolts.
Here is the project link (Tinkercad).
Code:
#include <LiquidCrystal.h>
// Adds the liquid crystal lib
int contrast = 40; // Set the contrast of the LCD
LiquidCrystal lcd (12, 11, 5, 4, 3, 2); // Instantiate the LCD
float fahrenheit;
float millivolts;
void setup ()
{
analogWrite(6, contrast); // Wrjte the contrast to the LCD
lcd.begin(16, 2); // Init the LCD
}
void loop ()
{
int sensor = analogRead(0);
millivolts = (sensor/1023.0)*5000;
fahrenheit = (((sensor*0.00488)-0.5)/0.01)*1.8+32;
lcd.setCursor(0, 0);
lcd.print("Temp(F):");
lcd.setCursor(11, 0);
lcd.print(fahrenheit);
lcd.setCursor(0, 1);
lcd.print("Volts(mV):");
lcd.setCursor(12, 1);
lcd.print(millivolts);
}
Diagram
I'm trying to get VGM CAN message out of a Reachstacker 42-45 tonnes
where I am using an arduino MEGA 2560 with a CAN-BUS shield
this my current code:
#include <SPI.h>
#include "mcp_can.h"
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
void setup()
{
Serial.begin(115200);
START_INIT:
if(CAN_OK == CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
{
Serial.println("CAN BUS Shield init ok!");
}
else
{
Serial.println("CAN BUS Shield init fail");
Serial.println("Init CAN BUS Shield again");
delay(100);
goto START_INIT;
}
}
void loop()
{
unsigned char len = 0;
unsigned char buf[8];
if(CAN_MSGAVAIL == CAN.checkReceive()) // check if data coming
{
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
unsigned char canId = CAN.getCanId();
Serial.println("-----------------------------");
Serial.println("get data from ID: ");
Serial.println(canId);
for(int i = 0; i<len; i++) // print the data
{
Serial.print(buf[i]);
Serial.print("\t");
}
Serial.println();
}
}
this was the result at the time of doing the test, the problem that I do not understand the result
according to the documentation should have a result like this :
this is another part of the documentation :
If someone needs more information or does not understand what I'm looking for, you can request what you need to help me
Send data:
// demo: CAN-BUS Shield, send data
#include <mcp_can.h>
#include <SPI.h>
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
void setup()
{
Serial.begin(115200);
START_INIT:
if(CAN_OK == CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
{
Serial.println("CAN BUS Shield init ok!");
}
else
{
Serial.println("CAN BUS Shield init fail");
Serial.println("Init CAN BUS Shield again");
delay(100);
goto START_INIT;
}
}
unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
void loop()
{
// send data: id = 0x00, standrad frame, data len = 8, stmp: data buf
CAN.sendMsgBuf(0x00, 0, 8, stmp);
delay(100); // send data per 100ms
}
You have two pieces that do not fit between your documentation and the output you are generating:
The data payload
The ID of the CAN frames
For the data payload it is simply a matter of formatting. You print each byte as integer value, whereas in the documentation it is printed as hexadecimal values. Use
Serial.print(buf[i], HEX)
to get the payload printed as hexadecimal characters.
For the ID of the CAN frames, you see from the documentation that they do not fit inside an unsigned char, as already mentioned in the comment by #Guille. Actually those are 29-bit identifiers, which you should ideally store in an appropriately sized variable. Ideally use an unsigned long:
unsigned long canId = CAN.getCanId();
In the documentation the CAN ID is also printed in hexadecimal, so also here use:
Serial.println(canId, HEX);
I have an application where I am using a MCP3421 18bit ADC to read analog data. The setup is Xbee+Xbee Sheild+Arduino + MCP3421 as Transmitter. This I am reading and transmitting to a remote xbee+arduino module with LCD. The data is displayed fine on the LCD. however I want to receive the data on the Serial port. When i try tp Do a Serial.println(s); on the receiving code the data which i get on serial port is garbled. Would appreciate any help
Here is my Code
Transmitting
#include <Wire.h>
#include <LiquidCrystal.h>
#define TRUE 1
#define FALSE 0
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup(void)
{
Serial.begin(9600);
Wire.begin();
delay(100);
Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>"); // just to be sure things are working
lcd.begin(16, 2);
}
void loop(void)
{
byte address, Hi, Lo, Config;
int ADVal;
while(1)
{
address = 0x68;
Wire.beginTransmission(address);
Wire.write(0x88); // config register %1000 1000
// /RDY = 1, One Conversion, 15 samples per, PGA = X1
Wire.endTransmission();
delay(1);
Wire.requestFrom((int)address, (int) 3);
Hi = Wire.read();
Lo = Wire.read();
Config = Wire.read();
Wire.endTransmission();
ADVal = Hi;
ADVal = ADVal * 256 + Lo;
// Serial.print(ADVal, DEC);
//Serial.print(" ");
//Serial.println(Config, DEC);
Serial.print("<");
Serial.print(ADVal);
Serial.print(">");
//lcd.setCursor(0,0);
//lcd.print(ADVal);
lcd.setCursor(0,1);
//float val = ADVal * 0.00006244087;
//lcd.print(val,3);
delay(1);
}
}
and this is the receiving code
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // initialize the library with the numbers of the interface pins
bool started = false;
bool ended= false;
char inData[10]; // Leave plenty of room
byte index;
float i;
//char inData[24]; // Or whatever size you need
//byte index = 0;
void setup(){
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// initialize the serial communications:
Serial.begin(9600);
}
void loop()
{
//Serial.println(s);
while(Serial.available() > 0)
{
char aChar = Serial.read();
if(aChar == '<')
{
// Start of packet marker read
index = 0;
inData[index] = '\0'; // Throw away any incomplete packet
started = true;
ended = false;
}
else if(aChar == '>')
{
// End of packet marker read
ended = true;
break; // Done reading serial data for now
}
else
{
if(index < 10) // Make sure there is room
{
inData[index] = aChar; // Add char to array
index++;
inData[index] = '\0'; // Add NULL to end
}
}
}
// When we get here, there is no more serial data to read,
// or we have read an end-of-packet marker
if(started && ended)
{
// We've seen both markers - do something with the data here
lcd.setCursor(0,0);
i = atoi (inData);
float s = (i * 0.3051851); //multiplying with calibration factor
float value = ( s / 1000 );
lcd.setCursor(1,0);
lcd.print(value,3); // print value after multiplying with calibration factor to LCD
lcd.setCursor(0,1 );
lcd.print(i); // Print raw ADC counts as recieved from transmitter
index = 0;
inData[index] = '\0';
started = false;
ended = false;
}
}
The receiving arduino do get the data through Xbee and it displays values perfectly on the LCD( Attached PIC). I also need to receive the data on a PC attached to the receiving arduino through its USB/Serial port.
When i try to use the serial monitor the display on LCD vanishes and the serial monitor displays garbled values. I thing the Serial.print(s) is sending back the data to the XBEE as both the DO and DI LED starts blinking on the XBEE SHIELD.