Arduino code works on MacBook Pro but not on Raspberry Pi 3B+ - serialization

I'm working on a project where I'm attempting to use an Adafruit optical fingerprint sensor, and I have it working great on my Mac. When I move the same wiring and code over the RPI, the code first doesn't compile, it says I must include the SoftwareSerial Library. When I add that, the code successfully uploads but then fails to find the fingerprint sensor. I'm using port dev/ttyACM0 on the RPI. I am using an example sketch for the fingerprint library shown below. I know the wiring works as it functions as intended on Mac. I'm a little new to this so help would be greatly appreciated. Thanks!
This is an example sketch for our optical Fingerprint sensor
Designed specifically to work with the Adafruit BMP085 Breakout
----> http://www.adafruit.com/products/751
These displays use TTL Serial to communicate, 2 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Adafruit_Fingerprint.h>
#if (defined(__AVR__) || defined(ESP8266)) && !defined(__AVR_ATmega2560__)
// For UNO and others without hardware serial, we must use software serial...
// pin #2 is IN from sensor (GREEN wire)
// pin #3 is OUT from arduino (WHITE wire)
// Set up the serial port to use softwareserial..
SoftwareSerial mySerial(2, 3);
#else
// On Leonardo/M0/etc, others with hardware serial, use hardware serial!
// #0 is green wire, #1 is white
#define mySerial Serial1
#endif
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
uint8_t id;
void setup()
{
Serial.begin(9600);
while (!Serial); // For Yun/Leo/Micro/Zero/...
delay(100);
Serial.println("\n\nAdafruit Fingerprint sensor enrollment");
// set the data rate for the sensor serial port
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println("Found fingerprint sensor!");
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1) { delay(1); }
}
Serial.println(F("Reading sensor parameters"));
finger.getParameters();
Serial.print(F("Status: 0x")); Serial.println(finger.status_reg, HEX);
Serial.print(F("Sys ID: 0x")); Serial.println(finger.system_id, HEX);
Serial.print(F("Capacity: ")); Serial.println(finger.capacity);
Serial.print(F("Security level: ")); Serial.println(finger.security_level);
Serial.print(F("Device address: ")); Serial.println(finger.device_addr, HEX);
Serial.print(F("Packet len: ")); Serial.println(finger.packet_len);
Serial.print(F("Baud rate: ")); Serial.println(finger.baud_rate);
}
uint8_t readnumber(void) {
uint8_t num = 0;
while (num == 0) {
while (! Serial.available());
num = Serial.parseInt();
}
return num;
}
void loop() // run over and over again
{
Serial.println("Ready to enroll a fingerprint!");
Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as...");
id = readnumber();
if (id == 0) {// ID #0 not allowed, try again!
return;
}
Serial.print("Enrolling ID #");
Serial.println(id);
while (! getFingerprintEnroll() );
}
uint8_t getFingerprintEnroll() {
int p = -1;
Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.println(".");
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
break;
default:
Serial.println("Unknown error");
break;
}
}
// OK success!
p = finger.image2Tz(1);
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
Serial.println("Remove finger");
delay(2000);
p = 0;
while (p != FINGERPRINT_NOFINGER) {
p = finger.getImage();
}
Serial.print("ID "); Serial.println(id);
p = -1;
Serial.println("Place same finger again");
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.print(".");
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
break;
default:
Serial.println("Unknown error");
break;
}
}
// OK success!
p = finger.image2Tz(2);
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
// OK converted!
Serial.print("Creating model for #"); Serial.println(id);
p = finger.createModel();
if (p == FINGERPRINT_OK) {
Serial.println("Prints matched!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_ENROLLMISMATCH) {
Serial.println("Fingerprints did not match");
return p;
} else {
Serial.println("Unknown error");
return p;
}
Serial.print("ID "); Serial.println(id);
p = finger.storeModel(id);
if (p == FINGERPRINT_OK) {
Serial.println("Stored!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_BADLOCATION) {
Serial.println("Could not store in that location");
return p;
} else if (p == FINGERPRINT_FLASHERR) {
Serial.println("Error writing to flash");
return p;
} else {
Serial.println("Unknown error");
return p;
}
return true;
}

Related

TinkerCAD Ardunio code error too few arguments

I'm building a robot for my class, and we have to have 2 servos and 1 DC motor working in a specific way. Everything is hooked up to an arduino uno, and my code works, but I using tinkercad to test a few things but I'm getting an error which is stopping my code from functioning in tinker cad, and I'm at a total loss.
ERROR
In function 'void loop()':
44:9: error: too few arguments to function 'void motor(char, char)'
17:6: note: declared here
exit status 1
CODE
#include <Servo.h> // set servo header to let ardduino know you intend to use a servo
Servo mycontinuousservo; // declare servos to be used
Servo mydegreeservo;
int In1 = 7; // declare your global variables to indicate pin numbers
int In2 = 8;
int pin = 6;
int servocontinuouspin = 10;
int servodegreepin = 9;
int angle = 90;
void servopos();
void servocontinous();
void motor(char Speed,char Direction);
void setup() {
// put your setup code here, to run once:
pinMode(In1, OUTPUT);
pinMode(In2, OUTPUT);
pinMode(pin, OUTPUT);
digitalWrite(In1, HIGH); //pin 7 moves forward
digitalWrite(In2, LOW); //pin 8 moves forward
analogWrite(pin, 0); // start at 0
pinMode(servocontinuouspin, OUTPUT);
pinMode(servodegreepin, OUTPUT);
mycontinuousservo.attach(servocontinuouspin);
mydegreeservo.attach(servodegreepin);
mycontinuousservo.write(90);
Serial.begin(9600); // for serial communication
}
void loop() {
servocontinous(); //call by ref aforedeclared functions
servopos();
motor();
}
// EXIT THE LOOP
void servopos() { //position function
int degree = 0;
int i = 0;
for (i = 0; i < 18; i++) {
mydegreeservo.write(degree);
delay(500); //delay 0.5 seconds
degree = degree + 10;
}
}
void servocontinous() // continous servo settings
{
for (int angle = 90; angle >= 0; angle--) {
mycontinuousservo.write(angle);
delay(50);
}
if (angle == 0) {
Serial.print("speed\n");
}
for (angle = 0; angle < 90; angle++)
{
mycontinuousservo.write(angle);
delay(50);
}
}
void motor() //motor function
{
char Speed = 0;
char Direction = 0;
if (Serial.available() > 0) //initialising
{
if (Direction == 'f') //70 representing F on the ASCII table
{
delay(500);
Serial.println("F");
}
if (Direction == 'r')
{
delay(500);
Serial.println("R");
}
}
if (Serial.available() > 0)
{
Speed = Serial.read();
if (Speed == '0')
{
Speed = 0;
Serial.println("Speed 0");
}
if (Speed == '1')
{
Speed = 14;
Serial.println("Speed 1");
}
if (Speed == '2')
{
Speed = 29;
Serial.println("Speed 2");
}
if (Speed == '3')
{
Speed = 42;
Serial.println("Speed 3");
}
if (Speed == '4')
{
Speed = 56;
Serial.println("Speed 4");
}
if (Speed == '5')
{
Speed = 70;
Serial.println("Speed 5");
}
if (Speed == '6')
{
Speed = 84;
Serial.println("Speed 6");
}
if (Speed == '7')
{
Speed = 98;
Serial.println("Speed 7");
}
if (Speed == '8')
{
Speed = 112;
Serial.println("Speed 8");
}
if (Speed == '9')
{
Speed = 128;
Serial.println("Speed 9");
}
} delay(5000);
analogWrite(pin, Speed);
if (Direction == 'f')
{ digitalWrite(In1, HIGH);
digitalWrite(In2, LOW);
} if (Direction == 'r')
{
digitalWrite(In1, LOW);
digitalWrite(In2, HIGH);
}
}
Here you declare the function as taking two arguments:
void motor(char Speed,char Direction);
Later you call it with no arguments, which is invalid when compared to that declaration:
motor();
This will be an immediate compiler error. That function is described as having two arguments, you call it with zero. Compile hard fails and stops because of this contradiction.
Yet when you define it the arguments are gone, they're actually local variables:
void motor() //motor function
{
char Speed = 0;
char Direction = 0;
// ...
}
This too contradicts the earlier declaration, so if you comment out the place where it's called you'll likely get a different error.
Local variables are the private business of a function, they do not need to be shown in the function signature, so don't think these need to be included as arguments.
What you need to do is either snip the arguments from the declaration, make sure that declaration matches the function signature exactly, or move the motor() function definition to before where it is first called.
I prefer to organize things so that pre-declaration is not necessary, or at least minimized. There's no reason to not put the motor() definition before loop().

How can I write code to receive whole string from a device on rs232?

I want to know how to write code which receives specific string.for example, this one OK , in this I only need "OK" string.
Another string is also like OK
I have written code in keil c51 for at89s52 microcontroller which works but I need more reliable code.
I'm using interrupt for rx data from rs232 serial.
void _esp8266_getch() interrupt 4 //UART Rx.{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
else
{
count=0;
do
{
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data1) //rx_data1 = 0X0D /CR
{
RI=0;
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data2) // rx_data2 = 0x0A /LF
{
RI=0;
data_in_buffer=1;
if(loop_conti==1)
{
if(rec_bit_flag==1)
{
data_in_buffer=0;
loop_conti=0;
}
}
}
}
else
{
if(data_in_buffer==1)
{
received[count]=rx_buff; //my buffer in which storing string
rec_bit_flag=1;
count++;
loop_conti=1;
RI=0;
}
else
{
loop_conti=0;
rec_bit_flag=0;
RI=0;
}
}
}
while(loop_conti==1);
}
rx_buff=0;
}
This is one is just for reference, you need develop the logic further to your needs. Moreover, design is depends on what value is received, is there any specific pattern and many more parameter. And this is not a tested code, I tried to give my idea on design, with this disclaimer here is the sample..
//Assuming you get - "OK<CR><LF>" in which <CR><LF> indicates the end of string steam
int nCount =0;
int received[2][BUF_SIZE]; //used only 2 buffers, you can use more than 2, depending on how speed
//you receive and how fast you process it
int pingpong =0;
bool bRecFlag = FALSE;
int nNofbytes = 0;
void _esp8266_getch() interrupt 4 //UART Rx.
{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
if(RI) // Rx interrupt
{
received[pingpong][nCount]=SBUF;
RI =0;
if(nCount > 0)
{
// check if you receive end of stream value
if(received[pingpong][nCount-1] == 0x0D) && (received[pingpong][nCount] == 0x0A))
{
bRecFlag = TRUE;
pingpong = (pingpong == 0);
nNofbytes = nCount;
nCount = 0;
return;
}
}
nCount++;
}
return;
}
int main()
{
// other stuff
while(1)
{
// other stuff
if(bRecFlag) //String is completely received
{
buftouse = pingpong ? 0 : 1; // when pingpong is 1, buff 0 will have last complete string
// when pingpong is 0, buff 1 will have last complete string
// copy to other buffer or do action on received[buftouse][]
bRecFlag = false;
}
// other stuff
}
}

PubSubClient & ArduinoJSON - Arduino passing char to digitalWrite

I am not sure how to pass the values in the function in order to be used within the digitalWrite functions.
I'm getting the following error:
error: cannot convert 'String' to 'uint8_t' {aka unsigned char}' for argument '1' to 'void digitalWrite(uint8_t, uint8_t)'
pubsub callback
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("New message on [");
Serial.print(topic);
Serial.print("] ");
Serial.println("");
char s[length];
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
s[i]=payload[i];
}
StaticJsonBuffer<500> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(s);
if (!root.success()) {
Serial.println("parseObject() failed");
}
String relay = root["relay"]; // "relayOne"
int time = root["timestamp"]; // 1351824120
String trigger = root["trigger"]; // "ON"
// Feel free to add more if statements to control more GPIOs with MQTT
commander(relay, trigger);
}
commander function
void commander(String relay, String trigger) {
if(trigger == "ON"){
Serial.print("Turning ");
Serial.println(relay);
Serial.println(" on");
digitalWrite(relay, HIGH);
} else if(trigger == "OFF"){
Serial.println(relay);
digitalWrite(relayOne, LOW);
Serial.print("TRIGGERED!");
} else {
// turn all the LEDs off:
for (int pin = 0; pin < relayPinCount; pin++) {
digitalWrite(relayPins[pin], LOW);
}
}
Serial.println();
}
void commander(String relay, String trigger) {
uint8_t pinNo;
if ( relay == "relayOne" ) {
pinNo = RELAY_1_PIN;
} else
if ( relay == "anotherRelay" ) {
pinNo = OTHER_RELAY_PIN;
} else
if ( ... ) {
...
} else {
return;
}
if(trigger == "ON"){
Serial.print("Turning ");
Serial.println(relay);
Serial.println(" on");
digitalWrite(pinNo, HIGH);
} else if(trigger == "OFF"){
Serial.println(relay);
digitalWrite(pinNo, LOW);
Serial.print("TRIGGERED!");
} else {
// turn all the LEDs off:
for (int pin = 0; pin < relayPinCount; pin++) {
digitalWrite(relayPins[pin], LOW);
}
}
Serial.println();
}

How to break infinite while in Arduino

A-R-D-U-I-N-O circuit that include pad number and a led with this code
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
void setup() {
pinMode(13,OUTPUT);
Serial.begin(9600);
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.println(key);
switch(key) {
case 'A':
while(1)
{
digitalWrite(13,HIGH);
delay(1000);
digitalWrite(13,LOW);
delay(1000);
}
break;
}
}
How can I make another case e.g. (case 'D') to stop this infinite while loop?
You can't exit the while loop therefore you will keep running the code
digitalWrite(13,HIGH);
delay(1000);
digitalWrite(13,LOW);
delay(1000);
You will never leave this loop in order to be able to run a case such as Case 'D'. You will need to put an if statement within the while loop that checks for whatever you want to be true. If it is true then you should break;
if (statement) break;
Well, actually you can't break that while from outside since the program will only be running those instructions inside the while loop. Maybe you should use another strategie. One would be the use of another variable that saves the option.
Something like:
void loop(){
int option = 0;
char key = keypad.getKey();
if (key)
{
Serial.println(key);
switch(key){
case 'A': option = 1; break;
case 'B': option = 2; break;
}
}
if(option == 1)
{
digitalWrite(13,HIGH);
delay(1000);
digitalWrite(13,LOW);
delay(1000);
}
else if(option == 2)
{...}
}
Looks like your "switch" case is a little malformed, I thought they always had to have a default case. Your code also seems to be missing the keypad includes/defines.
As for the problem could always have a flag that the two buttons turned on/off and then blink the led depending on that flag.
#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
byte rowPins[ROWS] = {5, 6, 7, 8}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A3, A2, A1, A0}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(Keys), rowPins, colPins, ROWS, COLS);
//yes i know that looks horrible
//would always have a different name for the keypad myself
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
int flag=0;
void setup() {
pinMode(13,OUTPUT);
Serial.begin(9600);
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.println(key);
switch(key) {
case 'A':
flag=1;
break;
case 'D':
flag=0;
break;
default:
break
}
}
if(flag){
digitalWrite(13,HIGH);
delay(1000);
digitalWrite(13,LOW);
delay(1000);
}
}
The only issue with that is that while delaying between blinks its not testing for key presses, so to turn off the flag you'd have to hold 'D' for over two seconds, maybe even tap it. Its been a while since I used one of those keypads.

Infix to Postfix Conversion

I'm trying to code that converts infix expressions to postfix expressions. Currently, the program works correctly if I enter for e.g "5+6" it will output the correct answer which is "5 6 +". The problem occurs when I enter more than one operator for e.g "5+6-3", it outputs and incorrect answer "+3-". Can someone please point out where I'm making the error ? Thanks, in advance !
void main(){
Stack *s = new Stack;
string input;
cout <<"Enter Expression"<<endl;
cin>>input;
InfixToPostfix(input);
system("PAUSE");
}
string InfixToPostfix(string input){
Stack *S = new Stack();
string postfix = "";
for (int i=0; i < input.length();i++){
if (input[i]== ' '||input[i]==',') continue;
else if (IsOperator(input[i]))
{
while(!S->IsStackEmpty() && S->StackTop() != '(' && HasHigherPrecedence(S->StackTop(),input[i]))
{
postfix=S->StackTop();
S->Pop();
}
S->Push(input[i]);
}
else if(IsOperand(input[i]))
{
postfix +=input[i];
}
else if (input[i] == '(')
{
S->Push(input[i]);
}
else if (input[i]==')')
{
while(!S->IsStackEmpty() && S->StackTop() != '('){
postfix += S->StackTop();
S->Pop();
}
S->Pop();
}
}
while(!S->IsStackEmpty()){
postfix +=S->StackTop();
S->Pop();
}
cout <<""<<postfix;
return postfix;
}
bool IsOperand(char C)
{
if(C>= '0' && C<= '9') return true;
if(C>= 'a' && C<= 'z') return true;
if(C>= 'A' && C<= 'Z') return true;
return false;
}
bool IsOperator(char C)
{
if(C=='+' || C== '-' || C =='*' || C == '/' ||C == '$')
{
return true;
}else{
return false;
}
}
int IsRightAssociative(char op)
{
if(op=='$'){
return true;
}else{
return false;
}
}
int GetOperatorWeight(char op){
int weight = -1;
switch(op)
{
case'+':
case '-':
weight=1;
break;
case '*':
case '/':
weight=2;
break;
case '$':
weight=3;
break;
}
return weight;
}
int HasHigherPrecedence ( char op1, char op2)
{
int op1Weight= GetOperatorWeight(op1);
int op2Weight = GetOperatorWeight(op2);
if(op1Weight == op2Weight)
{
if(IsRightAssociative(op1))
{
return false;
}else{
return true;
}
return op1Weight > op2Weight ? true:false;
}
}
One suggestion: use a tree, rather than a stack, as an intermediate data structure. Let the operator with lowest precedence be the root of the tree and build it recursively from there. Then walk through the tree from left to right, again recursively, to generate the postfix version. That way, you can also keep track of the maximum stack depth for the postfix version, which can be important as many hand-held RPN calculators, for example, have very limited stack depths.