Trouble Reading from Serial.readstring() arduino UNO - c

The objective is to enter "on" and "off" in COM port and switch the Pin 13. No matter what I do. It won't switch on or off. Need help. I tried to see if the string I entered is "on". It prints "on" but when I check for the result it shows its different. What is wrong?
String SData;
String SData1;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(13,OUTPUT);
digitalWrite(13,HIGH);
delay(5000);
digitalWrite(13,LOW);
delay(1000);
}
void loop() {
// put your main code here, to run repeatedly:
while(Serial.available()==0)
{
}
SData=Serial.readString();
SData1="on";
if(SData==SData1)
Serial.print("Same");
else
{
Serial.print("Different");
// Serial.print(SerialData-SerialData1);
Serial.print(".");
}
if(SData=="on")
{
digitalWrite(13,HIGH);
Serial.println("LED ON");
delay(2000);
}
Serial.println(SData);
if(SData=="off")
{
digitalWrite(13,LOW);
Serial.println("LED OFF");
delay(2000);
}
SData="";
}

Related

Arduino Interrupt with One Button

I am using Arduino Uno, I try to run servo constantly from 0 to 45 degrees when the interrupt button is pressed it should go to -30 degree and wait here. When the same button is pressed again, it should resume the constant action, which is swiping 0 to 45 degrees without <servo.h> library.
I tried to run like this:
const int servo = 11;
const int led = 13;
const int buttonPin = 2;
volatile int buttonState = 1;
void setup() {
Serial.begin(57600);
pinMode(led, OUTPUT);
pinMode(servo, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin),Button,CHANGE);
}
void loop() {
digitalWrite(led,HIGH);
for(int i=0;i<30;i++)
{
digitalWrite(servo,HIGH);
delayMicroseconds(1500);
digitalWrite(servo,LOW);
delayMicroseconds(18500);
}
delay(2000);
for(int i=0;i<30;i++)
{
digitalWrite(servo,HIGH);
delayMicroseconds(1000);
digitalWrite(servo,LOW);
delayMicroseconds(19000);
}
delay(2000);
}
void Button()
{
digitalWrite(led,LOW);
for(int i=0;i<30;i++)
{
digitalWrite(servo,HIGH);
delayMicroseconds(1833);
digitalWrite(servo,LOW);
delayMicroseconds(18167);
}
}
I have no problem coding my own PWM for each case but it turns out, the problem is a bit complicated than I was expecting because when we try to resume, I need to disable the interrupt function when pressing the same an interrupt button somehow.
Is it possible in this way or is there a better way to implement it?

Controlling UC1638 Graphical LCD screen

I am using Arduino Uno, trying to control LCD screen type UC1638 (240x128 monochrome) I want to fillup the screen in black). Searching up the internet I ended up using this code (written in C):
/* The below source code is from the LCD manufacturer, when he has no
idea about Arduino, this is translated from code he gave me for AVR
- I assume "sbit" is just Arduino GPIO settings, so I changed them
here accordingly - but I am not sure if it is the correct settings I
shall use for the LCD screen via Arduino
*/
#include "stdio.h"
#include "stdlib.h"
//sbit RST = P3^1;
//sbit CD = P3^0;
//sbit SCK = P1^0; //WRB=WR0
//sbit SDA = P1^1; //RDB=WR1
//sbit CS = P3^2;
void writei(unsigned char Cbyte)
{
unsigned char i;
digitalWrite(11, LOW); //CS=0;
digitalWrite(12, LOW); //CD=0;
for(i=0;i<8;i++) {
digitalWrite(SCK, LOW); // SCK=0;
digitalWrite(SDA, Cbyte&0x80?HIGH:LOW); // SDA=Cbyte&0x80?1:0;
digitalWrite(SCK, HIGH); // SCK=1;
Cbyte=Cbyte<<1;
}
digitalWrite(11, HIGH); // CS=1;
}
void writed(unsigned char Dbyte) {
unsigned char i;
digitalWrite(11, LOW); //CS=0;
digitalWrite(12, HIGH); //CD=1;
for(i=0;i<8;i++) {
digitalWrite(SCK, LOW); // SCK=0;
digitalWrite(SDA, Dbyte&0x80?HIGH:LOW); // SDA=Dbyte&0x80?1:0;
digitalWrite(SCK, HIGH); // SCK=1;
Dbyte=Dbyte<<1;
}
digitalWrite(11, HIGH); // CS=1;
}
void DelayMS(unsigned int MS)
{
unsigned char us,usn;
while(MS!=0)
{
usn=2;
while(usn!=0) { us=0xf6; while(us!=0){us--;}; usn--; }
MS--;
}
}
void LCD_INIT(void) {
//writei(0xe3);//system reset
digitalWrite(13, LOW); // RST=0;
DelayMS(10); //1ms
digitalWrite(13, HIGH); // RST=1;
DelayMS(500);//Delay more than 150ms.
writei(0xe1);//system reset
writed(0xe2);
DelayMS(2);
writei(0x04);//set column Address
writed(0x00);//
//writei(0x2f);// internal VLCD
//writei(0x26);// TC
writei(0xEb);//set bias=1/12
writei(0x81);//set vop
writed(90);// pm=106 Set VLCD=15V
writei(0xb8);//屏蔽MTP
writed(0x00);
writei(0xC4);//set lcd mapping control
//writei(0x00); //MY MX 0
writei(0xA3);//set line rate 20klps
writei(0x95); // PT0 1B P P
//writei(90);
writei(0xf1); //set com end
writed(159); //set com end 240*128
writei(0xC2);
writei(0x31); //APC
writed(0X91); // 1/0: sys_LRM_EN disable
writei(0xc9);
writed(0xad); // display
}
void setWindowsProgame() //com36--160 seg51--205
{
writei(0x04); //colum
writed(0x00);
writei(0x60); //page
writei(0x70);
writei(0xf4);
writed(0); //startx
writei(0xf6);
writed(239); //endx
writei(0xf5);
writed(0); //
writei(0xf7);
writed(15); //endy PANGE 16页
writei(0xf9); //窗口功能开
writei(0xC4);//set lcd mapping control
}
void display_black(void)
{
int i,j,k;
setWindowsProgame();
for(i=0;i<240;i++) {
for(j=0;j<18;j++) { writei(0x01); writed(0xff); }
}
}
void display_wirte ()
{
int i,j,k;
setWindowsProgame();
for(i=0;i<240;i++) {
for(j=0;j<18;j++) { writei(0x01); writed(0x00); }
}
}
void display_pic()
{
int i,j,K;
char d;
setWindowsProgame();
i=0;
K=0;
for(i=0;i<240*16;i++) //240*144
{
writei(0x01);
d=0xff; //d=PIC[K++];
writed(d);
}
}
void setup() {
// IO declaration: (GPIO setup)
pinMode(12, OUTPUT); // CD
pinMode(13, OUTPUT); // RST (RW)
pinMode(11, OUTPUT); // CS
pinMode(SCK, OUTPUT);
pinMode(SDA, OUTPUT);
LCD_INIT();
}
void loop(){
display_pic(); // Fill-up the screen in black
}
Notes:
The screen is 240*128 monochrome pixels.
Chip is UC1638
I am using Arduino Uno (if it helps regarding the available GPIOs)
I know about the "LiquidCrystal" library, but the examples gaven to me till now are for text screen of 16*2, not graphical screen - I believe that the GPIOs are completely different.
I want to "paint" the screen in black: Though the compilation passes OK, the LCD screen seems empty (transparent), but it has power - What I am doing wrong?
Thanks a lot
EDIT:
* I added SCK+SDA pins mark as output - Though I believe pins connected OK, the result is still the same. If the code is OK, then I will double check my pins...
I found and solved some problems in the code:
First, the delay of the delayms function in the source code is not accurate, so I replaced it with the delay function in Arduino.
Then, the value (90) of Vbias (command 0x81) set during LCD initialization is low. After changing to 200, the contrast is significantly improved.
Finally, this is the current code, which runs well on STM32F103C8T6:
#include <stdio.h>
#include <stdlib.h>
#define SDA PA7
#define SCK PA5
#define RST PB6
#define CS PB10
#define CD PB0
void writei(unsigned char Cbyte)
{
unsigned char i;
digitalWrite(CS, LOW); //CS=0;
digitalWrite(CD, LOW); //CD=0;
for(i=0;i<8;i++) {
digitalWrite(SCK, LOW); // SCK=0;
digitalWrite(SDA, Cbyte&0x80?HIGH:LOW); // SDA=Cbyte&0x80?1:0;
digitalWrite(SCK, HIGH); // SCK=1;
Cbyte=Cbyte<<1;
}
digitalWrite(CS, HIGH); // CS=1;
}
void writed(unsigned char Dbyte) {
unsigned char i;
digitalWrite(CS, LOW); //CS=0;
digitalWrite(CD, HIGH); //CD=1;
for(i=0;i<8;i++) {
digitalWrite(SCK, LOW); // SCK=0;
digitalWrite(SDA, Dbyte&0x80?HIGH:LOW); // SDA=Dbyte&0x80?1:0;
digitalWrite(SCK, HIGH); // SCK=1;
Dbyte=Dbyte<<1;
}
digitalWrite(CS, HIGH); // CS=1;
}
void LCD_INIT(void) {
//writei(0xe3);//system reset
digitalWrite(RST, LOW); // RST=0;
delay(10); //1ms
digitalWrite(RST, HIGH); // RST=1;
delay(500);//Delay more than 150ms.
writei(0xe1);//system reset
writed(0xe2);
delay(2);
writei(0x04);//set column Address
writed(0x00);
//writei(0x2f);// internal VLCD
//writei(0x26);// TC
writei(0xEb);//set bias=1/12
writei(0x81);//set vop
writed(200);// pm=106 Set VLCD=15V
writei(0xb8);//屏蔽MTP
writed(0x00);
writei(0xC4);//set lcd mapping control
//writei(0x00); //MY MX 0
writei(0xA3);//set line rate 20klps
writei(0x95); // PT0 1B P P
//writei(90);
writei(0xf1); //set com end
writed(159); //set com end 240*128
writei(0xC2);
writei(0x31); //APC
writed(0X91); // 1/0: sys_LRM_EN disable
writei(0xc9);
writed(0xad); // display
}
void setWindowsProgame() //com36--160 seg51--205
{
writei(0x04); //colum
writed(0x00);
writei(0x60); //page
writei(0x70);
writei(0xf4);
writed(0); //startx
writei(0xf6);
writed(239); //endx
writei(0xf5);
writed(0); //
writei(0xf7);
writed(19); //endy PANGE 16页
writei(0xf9); //窗口功能开
writei(0xC4);//set lcd mapping control
}
void display_black(void)
{
int i,j,k;
setWindowsProgame();
for(i=0;i<240;i++) {
for(j=0;j<20;j++) { writei(0x01); writed(0xff); }
}
}
void display_wirte()
{
int i,j,k;
setWindowsProgame();
for(i=0;i<240;i++) {
for(j=0;j<20;j++) { writei(0x01); writed(0x00); }
}
}
void display_pic()
{
int i,j,K;
char d;
setWindowsProgame();
i=0;
K=0;
for(i=0;i<240*20;i++) //240*144
{
writei(0x01);
d=0xff; //d=PIC[K++];
writed(d);
}
}
void setup() {
// IO declaration: (GPIO setup)
pinMode(CD, OUTPUT); // CD
pinMode(RST, OUTPUT); // RST (RW)
pinMode(CS, OUTPUT); // CS
pinMode(SCK, OUTPUT);
pinMode(SDA, OUTPUT);
LCD_INIT();
}
void loop(){
display_black(); // Fill-up the screen in black
delay(1000);
display_wirte();
delay(1000);
}

Xbee S2 Reading API frame

while i read API frames in ardiuno
in Serial window i got simply
FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF,FFFFFFFF
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (Serial.available()>=0){
for(int i=0;i<22;i++)
{
Serial.print(Serial.read(),HEX);
Serial.print(",");
}
Serial.println();
}
}
Plz someone give me a solution. i could not identify the problem
You're trying to read when Serial.available() indicates there isn't anything there to read, so Serial.read() is probably returning -1.
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (Serial.available()>0){
Serial.println(Serial.read(),HEX);
}
}
change the line serial.available()>=0 to serial.available()>22
u will get data.

Combined loops not working in Arduino

I have an arduino code which is doing tasks like this:
while (a=='A')
{
//do the task A
}
while (a=='B')
{
//do the task B
}
These loop run correctly when they are run separately. But the problem comes when I try to combine both loops i.e.
void loop ()
{
while (a=='A')
{
//do the task A
}
while (a=='B')
{
//do the task B
}
}
Below is the code in full details:
void loop()
{
////// admin
Serial.println("A or B");
delay(500);
char a = userinput();
delay(500);
while(a== 'A'){
Serial.println("Type Your Starting ID Number...");
while(1 ){
while (Serial.available()==false);
char e = Serial.read();
if(isdigit(e)==false) break;
startid = (startid*10)+(e - 48);
}
if(startid<=endid){
for(pageid=startid; pageid<=endid; pageid++)
{
Serial.print("Your Biometric ID # is ");
Serial.println(pageid);
delay(2000);
fingerenrollment(pageid);
delay(2000);
if(pageid == endid){
Serial.println("......Memory Is Full....");
while(1);
}
}
}
else{
Serial.println("Wrong Entry.......Please Reset Your Device.....");
while(1);
}
}
////// user
while(a=='B'){
lcd.print("WELCOME TO iPoll");
delay(2000);
lcd.clear();
lcd.print("Place Your Thumb");
delay(2000);
lcd.clear();
tempid = '\0';
Serial.println("Place your Thumb For Authentication");
delay(500);
while(true){
ID = fingerauthentication();
delay(500);
if(tempid != '\0') break;
}
delay(100);
resp = userinput();
delay(100);
lcd.clear();
datatrans(ID, resp);
}
}
If you need any more help, I am here. Just comment.
You seem to be stuck in an infinite while loop. Try changing while(a=='A') and while(a=='B') to if(a=='A') and if(a=='B'). The void loop() method in Arduino automatically acts like an infinite while loop, looping through the code within it forever.
while (a == 'A') loop is never ending because you never change the value of a. You need some a = something; somewhere in your code, or do what #Dan12-16 said. The same applies to 'B'.
And a couple of tips to make your code easier to read (in my opinion). Instead of using if (condition == false), you could use if (!condition). Choose while (1) or while (true), but don't mix them (I would choose the second one).

Sketch that responds to certain commands, how is it done?

Alright I have a half complete Arduino sketch at the moment. Basically the sketch below will blink an LED on a kegboard-mini shield if a string of chars equals *{blink_Flow_A}* However the LED only blinks once with the current sketch loaded on the Arduino. I will like the Arduino to blink repeatedly until the "stop" command is sent to the Arduino. I would eventually like to open a valve, keep it open until the valve receives to the close command then close the valve. The sketch looks like the following,
/*
* kegboard-serial-simple-blink07
* This code is public domain
*
* This sketch sends a receives a multibyte String from the iPhone
* and performs functions on it.
*
* Examples:
* http://arduino.cc/en/Tutorial/SerialEvent
* http://arduino.cc/en/Serial/read
*/
// global variables should be identified with _
// flow_A LED
int led = 4;
// relay_A
const int RELAY_A = A0;
// variables from sketch example
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
void setup() {
Serial.begin(2400); // open serial port, sets data rate to 2400bps
Serial.println("Power on test");
inputString.reserve(200);
pinMode(RELAY_A, OUTPUT);
}
void open_valve() {
digitalWrite(RELAY_A, HIGH); // turn RELAY_A on
}
void close_valve() {
digitalWrite(RELAY_A, LOW); // turn RELAY_A off
}
void flow_A_blink() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for one second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
void flow_A_blink_stop() {
digitalWrite(led, LOW);
}
void loop() {
// print the string when newline arrives:
if (stringComplete) {
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
if (inputString == "{blink_Flow_A}") {
flow_A_blink();
}
}
//SerialEvent occurs whenever a new data comes in the
//hardware serial RX. This routine is run between each
//time loop() runs, so using delay inside loop can delay
//response. Multiple bytes of data may be available.
void serialEvent() {
while(Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
If it makes any difference someone on IRC told me to research state machines scratches head
To blink a Led without blocking the program, i suggest you use Timer (and the TimerOne library). I make a quick sample code :
#include "TimerOne.h" //Include the librart, follow the previous link to download and install.
int LED = 4;
const int RELAY_A = A0;
boolean ledOn;
void setup()
{
pinMode(LED, OUTPUT)
Timer1.initialise(500000) // Initialise timer1 with a 1/2 second (500000µs) period
ledOn = false;
}
void blinkCallback() // Callback function call every 1/2 second when attached to the timer
{
if(ledOn){
digitalWrite(LED,LOW);
ledOn = false;
}
else{
digitalWrite(LED,HIGH);
ledOn = true;
}
}
void open_valve() {
digitalWrite(RELAY_A, HIGH); // turn RELAY_A on
}
void close_valve() {
digitalWrite(RELAY_A, LOW); // turn RELAY_A off
}
void serialEvent() {
while(Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n') {
stringComplete = true;
}
}
}
void loop()
{
// print the string when newline arrives:
if (stringComplete) {
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
if (inputString == "{blink_Flow_A}") {
Timer1.attachInterupt(blinkCallback); //Start blinking
}
if (inputString == "{stop}") {
Timer1.detachInterrupt(); //Stop blinking
}
if (inputString == "{open_valve}") {
open_valve();
}
if (inputString == "{close_valve}") {
close_valve();
}
}
Note :
Consider putting the tag 'c' or 'java' to have syntax highlighting on the code.
A state machine (at it's simplest - it can be lots more complicated) can be just a set of conditional statements (if/else or switch/case) where you do certain behaviors based on the state of a variable, and also change that variable state. So it can be thought of as a way of handling or progressing through a series of conditions.
So you have the state of your LED/valve - it is either blinking (open) or not blinking (closed). In pseudo code here:
boolean LED_state = false; //init to false/closed
void loop(){
if (checkForCorrectCommand() == true){ //
if (LED_State == false){
open_valve();
LED_State = true;
} else {
close_valve();
LED_State = false;
}
}
}
The blinking LED part should be easy to implement if you get the gist of the code above. The checkForCorrectCommand() bit is a function you write for checking whatever your input is - key, serial, button, etc. It should return a boolean.
Perhaps something like the 'blink without delay' example in the IDE. You check the time and decide to when and how to change the LED/Digital out.
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)
void setup(){
// Your stuff here
}
void loop()
{
// Your stuff here.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
Let me offer a suggested sketch with a few changes. Bastyen's idea of using a timer is quite good and makes the code much easier. The approach I would suggest is to have the timer pop forever at a fixed interval (100 milliseconds in my sketch). If the LED should not be blinking it stays off. If the LED should be blinking, it switches from off to on or vice versa each time the timer goes off.
#include "TimerOne.h"
/*
* kegboard-serial-simple-blink07
* This code is public domain
*
* This sketch sends a receives a multibyte String from the iPhone
* and performs functions on it.
*
* Examples:
* http://arduino.cc/en/Tutorial/SerialEvent
* http://arduino.cc/en/Serial/read
*/
// global variables should be identified with _
// flow_A LED
int led = 4;
// relay_A
const int RELAY_A = A0;
// variables from sketch example
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
boolean shouldBeBlinking = false;
boolean ledOn = false;
void setup() {
Serial.begin(9600); // open serial port, sets data rate to 2400bps
Serial.println("Power on test");
inputString.reserve(200);
pinMode(RELAY_A, OUTPUT);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
Timer1.initialize(100000);
Timer1.attachInterrupt(timer1Callback);
}
void loop() {
if (!stringComplete)
return;
if (inputString == "{blink_Flow_A}")
flow_A_blink_start();
if (inputString == "{blink_Flow_B}")
flow_A_blink_stop();
inputString = "";
stringComplete = false;
}
void timer1Callback() {
/* If we are not in blinking mode, just make sure the LED is off */
if (!shouldBeBlinking) {
digitalWrite(led, LOW);
ledOn = false;
return;
}
/* Since we are in blinking mode, check the state of the LED. Turn
it off if it is on and vice versa. */
ledOn = (ledOn) ? false : true;
digitalWrite(led, ledOn);
}
void flow_A_blink_start() {
shouldBeBlinking = true;
open_valve();
}
void flow_A_blink_stop() {
shouldBeBlinking = false;
close_valve();
}
void close_valve() {
digitalWrite(RELAY_A, LOW); // turn RELAY_A off
}
void open_valve() {
digitalWrite(RELAY_A, HIGH); // turn RELAY_A on
}
//SerialEvent occurs whenever a new data comes in the
//hardware serial RX. This routine is run between each
//time loop() runs, so using delay inside loop can delay
//response. Multiple bytes of data may be available.
void serialEvent() {
if (stringComplete)
return;
while(Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString unless it is a newline
if (inChar != '\n')
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
else {
stringComplete = true;
}
}
}
A few notes:
The setup function establishes the timer with a 100 millisecond interval and attaches the callback routine. Based on my testing, this only needs to be done once.
The main loop just ignores everything unless an input string is complete. If an input string is ready, then the input string is checked for two known values and the appropriate steps are taken. The input string is then discarded.
The timer callback routine forces the LED off, if we are not in blinking mode. Otherwise, it just toggles the state of the LED.
The flow on and flow off routines set the blinking state as need be and control the valve
The serial event routine has two changes. First, input is ignored (and kept in the buffer) if an input string is already complete. This will preserve commands that are being sent to the Arduino while the current command is being processed. Second, the newline character is not added to the input string. This makes checking the input string slightly easier.

Resources