Can't get original value after sending by serial port - c++

I have written a simple code for sending int value using bluetooth serial port.
Transmitter:
#include <SoftwareSerial.h>
#include "PWM.hpp"
PWM PWM(2);
SoftwareSerial BTSerial(8,9);
void setup()
{
Serial.begin(9600);
Serial.println("Go");
BTSerial.begin(9600);
BTSerial.write("AT+INQ\r\n");
delay(10000);
BTSerial.write("AT+CONN1\r\n");
delay(100);
PWM.begin(true);
}
void loop()
{
int pwmValue = PWM.getValue();
Serial.println(pwmValue);
BTSerial.write(pwmValue);
delay(100);
}
Output of Serial.println of transmitter part is correct:
1500
but on receiver part isn't. This is the code of receiver:
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8, 9);
void setup() {
Serial.begin(9600);
BTSerial.begin(9600);
BTSerial.write("AT+NAME=Remote\r\n");
}
void loop() {
if (BTSerial.available()) {
int pwmValue = BTSerial.read();
Serial.println(pwmValue);
}
Incorrect output of Serial.println is:
220
I think the issue is in typecasting.

SoftwareSerial::read is returning a single byte read.
If you examine the expected 1500 in hexadecimal it is 0x05DC, and it's lower byte is 0xDC which is exactly 220 in decimal.

With the multi-byte variant of write() you could use:
BTSerial.write(&pwmValue, sizeof pwmValue);
For receiving you need a loop:
union {
int i;
char c[0];
} pwmValue;
int receivedBytes = 0;
void loop() {
if (BTSerial.available()) {
pwmValue.c[receivedBytes] = BTSerial.read();
receivedBytes++;
if (receivedBytes == sizeof pwmValue) {
Serial.println(pwmValue.i);
receivedBytes = 0;
}
}
}

In documentation https://github.com/PaulStoffregen/SoftwareSerial/blob/master/SoftwareSerial.cpp, you can see that both functions work with uint_8t -- which is guaranteed to have 8 bits (1 byte). That holds up to 256 of value, so 1500 mod 256 is 220.
Looks like the library is prepared to transmit only char-sized data, so you need to convert bigger numbers on both size.
For sending int:
int n = pwmValue;
while (n > 0) {
int digit = n % 10;
n = n / 10;
BTSerial.write(digit);
}
For receiving int:
int n = 0; //future result
int decs = 1;
int temp;
while ((temp = BTSerial.read()) != -1) {
n += temp * decs;
decs *= 10;
}

Related

Shift register stops working after I send one piece of code with my arduino

I have been stuck with this problem for multiple days now and can't seem to find a fix. The problem is that after I send a command to my shift register it doesn't accept more commands.
I'm using an arduino UNO with a 74HC595 shift register.
The problem occurs in the manualOverWrite function.
uint8_t RFIDPinValues[] = { B00000101 };
sr.setAll(RFIDPinValues);
delay(4000);
uint8_t RFIDOffPinValues[] = { B00001000 };
sr.setAll(RFIDOffPinValues);
When I run this piece of my code it turns on a relay(pin 0) and stops. All my arduino code keeps working except the shift register.
#include <SPI.h>
#include <ShiftRegister74HC595.h>
byte readCard[4];
String MasterTag0 = "*******";
String MasterTag1 = "********";
String tagID = "";
//declare arduino pins
int overWrite = 0;
// Create instances
const int numberOfShiftRegisters = 1; // number of shift registers attached in series
int serialDataPin = 11;
int clockPin = 12;
int latchPin = 8;
ShiftRegister74HC595<numberOfShiftRegisters> sr(serialDataPin, clockPin, latchPin);
void setup() {
Serial.begin(115200);
Serial.println("Startup");
// Initiating inputs
pinMode(overWriteButton, INPUT);
// set base state
sr.setAllLow();
uint8_t startValues[] = { B00001000 };
sr.setAll(startValues);
}
void loop() {
//ez to use vars
overWrite = digitalRead(overWriteButton);
manualOverWrite();
}
void manualOverWrite() {
if(overWrite == HIGH) {
uint8_t turnOnPinValues[] = { B00000101 };
sr.setAll(turnOnPinValues);
delay(5000);
uint8_t turnOffPinValues[] = { B00001000 };
sr.setAll(turnOffPinValues);
}
else {
uint8_t turnOn2PinValues[] = { B00001000 };
sr.setAll(turnOn2PinValues);
}
}
My apologies for the mess
https://mega.nz/file/NEYFiAAA#Rc4QUpv6cnL-_1NJJrjKe-IaInH_33wGJlHpGlVkySM

Trying to write character from Arduino pin to Putty

So, i am writing a code to send a character (8 data-bits) and a stop bit to Putty using the Arduino timer 1 interrupt. When I try to send a character it shows something in Putty, so it does send, but not the character I am sending. I have searched for all sorts of documentation but i can't seem to find what i need, also I don't know what I'm doing wrong. Code:
#define Fosc 16000000
int rxPin = 7;
int txPin = 8;
int dataBits = 0;
uint8_t txBuffer;
void setup() {
Serial.begin(9600);
pinMode(txPin, OUTPUT);
pinMode(rxPin, INPUT);
setupInterrupts(9600);
}
void loop() {
ReadMessage();
}
void setupInterrupts(long baud)
{
long cmr = ((Fosc / (64 * baud)) - 1); //compare match register
noInterrupts();
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0; //counter value to 0
OCR1A = cmr;
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS11) | (1 << CS10); // Set bits for 64 prescaler
//TIMSK1 = _BV(OCIE1A); //attach
interrupts();
}
ISR(TIMER1_COMPA_vect)
{
transmit();
}
void transmit()
{
if (dataBits < 8)
{
if (txBuffer & 0b1) {
digitalWrite(txPin, HIGH);
}
else {
digitalWrite(txPin, LOW);
}
txBuffer >>= 1;
}
dataBits++;
if (dataBits == 9)
{
dataBits = 0;
digitalWrite(txPin, HIGH);
TIMSK1 &= ~_BV(OCIE1A); //detach
}
}
bool getParity(unsigned int n)
{
bool parity = 0;
while (n)
{
parity = !parity;
n = n & (n - 1);
}
return parity;
}
int incomingByte;
void ReadMessage() {
if (Serial.available() > 0) {
incomingByte = Serial.read();
char receivedCharacter = (char) incomingByte;
txBuffer = receivedCharacter;
Serial.println((char)txBuffer);
TIMSK1 = _BV(OCIE1A); //attach
}
}
Putty Output

strcmp brakes Arduino sketch

For a school project, I'm using an Arduino Uno together with a Parallax RFID, a LCD screen and an esp8226-wifi module.
I'm trying to compare the scanned tag with the tags in the database and send the name of the tag owner to a terminal in the Blynk app. Everything works just fine until I put in the function that compares the tags. If I do that, everything stops working, even the code in the setup() part. How can I fix this?
I think the problem has somehing to do with the strcmp.
/* Libraries that need to be manually installed:
Blynk libraries: https://github.com/blynkkk/blynk-library/releases/download/v0.5.0/Blynk_Release_v0.5.0.zip
LiquidCrystal_I2C library: https://cdn.instructables.com/ORIG/FVH/K8OQ/J8UH0B9U/FVHK8OQJ8UH0B9U.zip
*/
#define BLYNK_PRINT Serial
#include <SoftwareSerial.h>
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//Setting up the Blynk wifi connection
#define ESP8266_BAUD 9600
char auth[] = "87b00838cd834e4e87a0422265cc7a9e";
char ssid[] = "bbox2-56b2";
char pass[] = "91C2D797F6";
//Setting up the virtual pins
WidgetTerminal terminal(V1);
BLYNK_WRITE(V1){}
//Setting up the RFID
#define RFIDEnablePin 8
#define RFIDSerialRate 2400
String RFIDTAG=""; //Holds the RFID Code read from a tag
String DisplayTAG = ""; //Holds the last displayed RFID Tag
//Setting up the LCD
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//Setting up the serial connection
SoftwareSerial EspSerial(2, 3);
ESP8266 wifi(&EspSerial);
void setup()
{
//Serial communication
Serial.begin(RFIDSerialRate);
EspSerial.begin(ESP8266_BAUD);
Serial.begin(RFIDSerialRate);
delay(10);
//Blynk setup
Blynk.begin(auth, wifi, ssid, pass);
//LCD setup
lcd.begin(16,2);//16 kolommen, 2 rijen
lcd.backlight();
//RFID setup
pinMode(RFIDEnablePin,OUTPUT);
digitalWrite(RFIDEnablePin, LOW);
terminal.println("Terminal printing succesfull");
terminal.flush();
}
void loop()
{
if(Serial.available() > 0)
{
ReadSerial(RFIDTAG);
}
if(DisplayTAG!=RFIDTAG)
{
DisplayTAG=RFIDTAG;
// PROBLEM STARTS HERE
//Tag database
char tags[10][10] = {"6196", "6753", "5655", "69EC", "9FFC"};
char owners[10][30] = {"per1", "per2", "per3", "per4", "per5"};
int i = 0;
int j = 0;
int ownerLength = 0;
char lastTag[10];
RFIDTAG.toCharArray(lastTag, 10);
while (i < 10)
{
if (strcmp(tags[i], lastTag) == 0)
{
ownerLength = strlen(owners[i]);
while (j < ownerLength)
{
terminal.print(owners[i][j]);
}
terminal.println("has entered the parking\n\r");
terminal.flush();
break;
}
i++;
}
i = 0;
j = 0;
//PROBLEM ENDS HERE
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Last tag:");
lcd.setCursor(0,1);
lcd.print(RFIDTAG);
digitalWrite(RFIDEnablePin, HIGH);
delay(1000);
digitalWrite(RFIDEnablePin, LOW);
}
Blynk.run();
}
//Function for reading the tag
void ReadSerial(String &ReadTagString)
{
int bytesread = 0;
int val = 0;
char code[10];
String TagCode="";
if(Serial.available() > 0)
{
if((val = Serial.read()) == 10)
{
bytesread = 0;
while(bytesread<10) // Reads the tag code
{
if( Serial.available() > 0)
{
val = Serial.read();
if((val == 10)||(val == 13)) // If header or stop bytes before the 10 digit reading
{
break; // Stop reading
}
code[bytesread] = val; // Add the digit
bytesread++; // Ready to read next digit
}
}
if(bytesread == 10) // If 10 digit read is complete
{
for(int x=6;x<10;x++) //Copy the Chars to a String
{
TagCode += code[x];
}
ReadTagString = TagCode; //Returns the tag ID
while(Serial.available() > 0) //Burn off any characters still in the buffer
{
Serial.read();
}
}
bytesread = 0;
TagCode="";
}
}
}

How to store numbers in Arduino?

I have written this to an Arduino.
char incomingbytea;
char incomingbyteb;
char incomingop;
char result;
void setup()
{
Serial.begin(9600);
}
void loop(){
incomingbytea = 0;
incomingbyteb = 0;
incomingop = 0;
result = 0;
bytea:
if (Serial.available() > 0) {
incomingbytea = Serial.read();
Serial.println("1ok");
Serial.println(incomingbytea);
goto byteb;
}
goto bytea;
byteb:
if (Serial.available() > 0) {
incomingbyteb = Serial.read();
Serial.println("2ok");
Serial.println(incomingbyteb);
goto op;
}
goto byteb;
op:
if (Serial.available() > 0) {
incomingop = Serial.read();
Serial.println("opok");
Serial.println(incomingop);
goto oper;
}
goto op;
oper:
result = incomingbytea + incomingbyteb;
Serial.println(result);
Serial.println(incomingbytea);
Serial.println(incomingbyteb);
Serial.println(incomingop);
}
What I want to do is:
- connect to serial (check)
- collect 2 variables to add/subtract/multiply/divide later (check)
- collect a variable to decide what to do with them 1-add, 2-subtract, etc. (check)
- redirect the script to do the required operation (later)
- print the result to serial (check)
The problem is, when I enter 1 and 1 and 1(whatever, the third one doesn't count now) and I get 98 as a result. Any help? Maybe the variables are wrong?
First you should know the length of the number, and subtract 48 (48 is the ascii representation of 0) later multiply the number for 1, 10, 100, 1000, 10000, ... depending of the position of each number.
For example: String "233" to integer, using custom method
void setup() {
Serial.begin(9600);
}
void loop() {
String Numero1 = "40";
String Numero2 = "50";
double Suma = StringAInt(Numero1)+StringAInt(Numero2);//+ StringAInt(Numero2);
Serial.println(Suma);
}
double StringAInt(String Dato)
{
String Numero = Dato;
char Valores [Numero.length()+1];
Numero.toCharArray(Valores,Numero.length()+1);
double NumeroEnt = 0;
for(int i = 0; i<Numero.length(); i++)
{
int NumValores = Valores[i];
NumValores-=48;
double MultPor = pow(10,Numero.length()-(i+1));
NumeroEnt += (NumValores*MultPor);
//Serial.println(NumValores*MultPor);
}
return NumeroEnt;
}
Now you only need build a string with the data received from serial port, and you can do math simply.

Testing arduino gps

Me and and a friend of mine are building a robot which contains a gps for arduino. We built the following circuit, to test the gps:
We're trying the following code to test the gps:
#include <SoftwareSerial.h>
#include <TinyGPS.h>
long lat,lon; // create variable for latitude and longitude object
SoftwareSerial gpsSerial(2, 3); // create gps sensor connection
TinyGPS gps; // create gps object
void setup(){
Serial.begin(9600); // connect serial
gpsSerial.begin(4800); // connect gps sensor
}
void loop(){
Serial.print("test"); //I implemented this test
while(gpsSerial.available()){ // check for gps data
Serial.print("test2"); //I implemented this test
if(gps.encode(gpsSerial.read())){ // encode gps data
Serial.print("test3"); //I implemented this test
gps.get_position(&lat,&lon); // get latitude and longitude
// display position
Serial.print("Position: ");
Serial.print("lat: ");Serial.print(lat);Serial.print(" ");// print latitude
Serial.print("lon: ");Serial.println(lon); // print longitude
}
}
}
The thing is that the serial monitor does output test number 1, but doesn't output test number 2 and number 3. So we expected the circuit we built to fail. But we double checked the wires etc. Does anybody know what the problem could be?
Any inspiration/help is welcome,
Thanks,
Justin van Til
Try this code.
#include <SoftwareSerial.h>
#include <TinyGPS.h>
TinyGPS gps;
static void print_long(long val, long invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);
SoftwareSerial ss(3,4);
void setup()
{
Serial.begin(9600);
ss.begin(9600);
}
void loop()
{
long lat, lon;
int alt;
unsigned short sentences = 0, failed = 0;
gps.get_position(&lat, &lon);
alt=gps.altitude();
Serial.print("CURRENT LATITUDE & LONGITUDE:");
Serial.print(lat);
Serial.print(",");
Serial.println(lon);
Serial.print("CURRENT ALTITUDE:");
Serial.println(alt);
smartdelay(1000);
}
static void smartdelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void print_long (long val, long invalid, int len, int prec)
{
if (val == invalid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; ++i)
Serial.print(' ');
}
smartdelay(0);
}
static void print_int(unsigned long val, unsigned long invalid, int len)
{
char sz[32];
if (val == invalid)
strcpy(sz, "*******");
else
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i<len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len-1] = ' ';
Serial.print(sz);
smartdelay(0);
}
static void print_str(const char *str, int len)
{
int slen = strlen(str);
for (int i=0; i<len; ++i)
Serial.print(i<slen ? str[i] : ' ');
smartdelay(0);
}