why the output not follow the setcursor? - arduino

Why is the output of the function does not follow the lcd.setCursor position? When type in, the output pops out at a different position instead of the determined setcursor. I need to use this function multiple times for different variables that hold a different number for a different purpose. However, I need the display of the numbers on the LCD according to the set position.
Here is the code:
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the
LCD I2C address
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
{
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {9,8,7,6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5,4,3}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup()
{
Serial.begin(9600);
lcd.begin(20,4);
}
void loop()
{
lcd.setCursor(2,0);
int stage1speed = getnumber();
lcd.setCursor(5,0);
lcd.print("sv");
lcd.setCursor(2,1);
int stage1time = getnumber();
lcd.setCursor(5,1);
lcd.print("sec");
lcd.setCursor(2,2);
int stage2speed = getnumber();
lcd.setCursor(5,2);
lcd.print("sec");
lcd.setCursor(2,3);
int stage2time = getnumber();
lcd.setCursor(5,3);
lcd.print("sec");
}
int getnumber()
{
static char buffer[4];
static byte i = 0;
char key = keypad.getKey();
// i < 3: prevent buffer overflow
if ('0' <= key && key <= '9' && i < 3)
{
buffer[i] = key;
++i;
} else if (key == '#' && i > 0)
{
buffer[i] = '\0'; // null-terminate buffer
int value = atoi(buffer);
lcd.print(buffer);
i = 0;
}
}

Related

I need the value to go up on 7 segment. help me pls

why is it like this How should I fix it?
It's my first time using PMS5003 with 7segment
I am able to display the value in the Serial Monitor but cannot get the pm2_5 value to be displayed in the 7 segment.
#include "SevSeg.h"
#include <SoftwareSerial.h>
SoftwareSerial mySerial(A0, A1);
SevSeg sevseg;
unsigned int pm1 = 0;
unsigned int pm2_5 = 0;
unsigned int pm10 = 0;
void setup() {
Serial.begin(9600);
while (!Serial) ;
mySerial.begin(9600);
byte numDigits = 4;
byte digitPins[] = {10, 11, 12, 13};
byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9}; //6, 7, 8, 9, 10, 11, 12, 13
bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
byte hardwareConfig = COMMON_CATHODE; // See README.md for options
bool updateWithDelays = false; // Default 'false' is Recommended
bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
sevseg.setBrightness(30);
}
void loop() {
int index = 0;
char value;
char previousValue ;
static unsigned long timer = millis ();
static int deciSeconds = 0;
if (millis() - timer >= 100)
{
timer += 100;
sevseg.setNumber(pm2_5, 2);
}
sevseg.refreshDisplay();
while (mySerial.available()) {
value = mySerial.read();
if ((index == 0 && value != 0x42) || (index == 1 && value != 0x4d)) { //0x42,0x4d ค่าคงที่
Serial.println("Cannot find the data header.");
break;
}
if (index == 4 || index == 6 || index == 8 || index == 10 || index == 12 || index == 14) {
previousValue = value;
}
else if (index == 5) {
pm1 = 256 * previousValue + value;
Serial.print("{ ");
Serial.print("\"pm1\": ");
Serial.print(pm1);
Serial.print(" ug/m3");
Serial.print(", ");
}
else if (index == 7) {
pm2_5 = 256 * previousValue + value;
Serial.print("\"pm2_5\": ");
Serial.print(pm2_5);
Serial.print(" ug/m3");
Serial.print(", ");
}
else if (index == 9) {
pm10 = 256 * previousValue + value;
Serial.print("\"pm10\": ");
Serial.print(pm10);
Serial.print(" ug/m3");
} else if (index > 15) {
break;
}
index++;
}
while (mySerial.available()) mySerial.read();
Serial.println(" }");
delay(1000);
}
I want the 7segment to be able to display the value of the sensor PMS5003.

Arduino hex to string decoder not working

I'm creating a HEX -> STR decoder using an LCD screen (display the HEX as well as the decoded values), a keypad (to input the HEX code), and a button (to press for it to decode the HEX values). The decoder works sometimes but sometimes it glitches out and presents unexpected values.
#include <Keypad.h>
#include<LiquidCrystal.h>
String hex; // store the hex values
String text; // store the decoded text
int calcButton = 0;
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'F'},
{'4', '5', '6', 'E'},
{'7', '8', '9', 'D'},
{'A', '0', 'B', 'C'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {13, 12, 11, 10};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
LiquidCrystal lcd(5, 4, 3, 2, A0, A1);
char nibble2c(char c) {
if ((c>='0') && (c<='9'))
return c-'0' ;
if ((c>='A') && (c<='F'))
return c+10-'A' ;
if ((c>='a') && (c<='a'))
return c+10-'a' ;
return -1 ;
}
char hex2c(char c1, char c2) {
if(nibble2c(c2) >= 0)
return nibble2c(c1)*16+nibble2c(c2) ;
return nibble2c(c1) ;
}
// resets string values and clears screen
void erase() {
hex = "";
Serial.println(hex);
text = "";
lcd.clear();
lcd.setCursor(0,0);
}
// decode the hex values
String calculate(String hex) {
if (hex.length()%2 != 0) {
lcd.setCursor(0,0);
lcd.print("No of characters");
lcd.setCursor(0,1);
lcd.print("needs to be even");
delay(2000);
erase();
}
else {
for (int i = 0; i < hex.length() - 1; i+=2){
for (int j = 1; j < hex.length(); j+=2){
text += hex2c(hex[i], hex[j]);
}
}
}
}
void setup() {
pinMode(A2, INPUT);
lcd.begin(16, 2);
lcd.setCursor(0,0);
Serial.begin(9600);
}
void loop() {
calcButton = digitalRead(A2); // decode button
char customKey = customKeypad.getKey();
// if keypad is pressed, add hex values to str
if (customKey){
lcd.print(customKey);
hex += customKey;
Serial.println(hex);
}
// if button is pressed, decode
if (calcButton == 1) {
lcd.clear();
calculate(hex);
hex = "";
lcd.print(text);
text = "";
delay(1500);
lcd.clear();
}
}
I input 49 and get I (which is correct) but when I input 4949 I expect the output to be II but it outputs IIII and when I input 6F expecting o the entire screen blurs and glitches.
The problem is here:
for (int i = 0; i < hex.length() - 1; i+=2){
for (int j = 1; j < hex.length(); j+=2){
text += hex2c(hex[i], hex[j]);
}
}
Notice that you iterate over the hex string length()*length()/4 times, combining every even hex character from the string with every odd character in the string, not just the one immediately following it. For two-digit hexadecimal strings this works because there only is one odd- and one even-indexed character; for longer strings you get wrong results.
4949 will combine 4 (#0) and 9 (#1), then 4 (#0) and 9 (#3) (wrong!), then 4 (#2) and 9 (#1) (wrong!), then 4 (#2) and 9 (#3), which gives you the result that 49494949 should give instead of 4949.
What you want is just:
for (int i = 0; i < hex.length() - 1; i+=2){
text += hex2c(hex[i], hex[i+1]);
}

Redeclared as different kind of symbol in Arduino

I'm currently working on a school project. I want the servo to move according to the number of coins selected. I keep getting the error " 'void servoOne()' redeclared as different kind of symbol " I know this has been asked but I'm not sure how to fix this.
Here is my code.
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <Servo.h>
Servo servoOne;
String sharp="";
int piso=0;
int lima=0;
int sampu=0;
String input="";
String remlast = "";
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);//RS,EN,D4,D5,D6,D7
const byte Rows= 4; //number of rows on the keypad i.e. 4
const byte Cols= 3; //number of columns on the keypad i,e, 3
//we will definne the key map as on the key pad:
char keymap[Rows][Cols]={
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rPins[Rows]= {3,4,5,6}; //Rows 0 to 3
byte cPins[Cols]= {7,8,9}; //Columns 0 to 2
Keypad kpd= Keypad(makeKeymap(keymap), rPins, cPins, Rows, Cols);
void setup() {
// put your setup code here, to run once:
lcd.begin(20,4);
servoOne.attach(10);
}
void loop() {
char key2 = kpd.getKey();
if (key2 != NO_KEY)
{
lcd.print(key2);
if (sharp == "")
{
input+=key2;
remlast = input;
remlast.replace("*","");
remlast.replace("#","");
piso = remlast.toInt();
}
else if (sharp == "five")
{
input+=key2;
remlast = input;
remlast.replace("*","");
remlast.replace("#","");
lima = remlast.toInt();
}
else if (sharp == "ten")
{
input+=key2;
remlast = input;
remlast.replace("*","");
remlast.replace("#","");
sampu = remlast.toInt();
}
if(key2=='*' && sharp!=NULL)
{
lcd.rightToLeft();
sharp="";
piso=0;
lima=0;
sampu=0;
input="";
remlast="";
}
if (sharp=="ten" && key2=='#')
{
sharp = "out";
lcd.clear();
lcd.print(piso);
lcd.print(lima);
lcd.print(sampu);
servoOne();
}
else if (sharp=="five" && key2=='#')
{
lcd.clear();
lcd.print("10-peso=");
lcd.setCursor(0,1);
lcd.print("(*)Erase (#)Enter");
lcd.setCursor(8,0);
sharp="ten";
input = 0;
}
else if (key2=='#')
{
lcd.clear();
lcd.print("5-peso=");
lcd.setCursor(0,1);
lcd.print("(*)Erase (#)Enter");
lcd.setCursor(7,0);
sharp="five";
input = 0;
}
if (key2=='*')
{
lcd.clear();
lcd.print("1-peso=");
lcd.setCursor(0,1);
lcd.print("(*)Erase (#)Enter");
lcd.setCursor(7,0);
}
}
}
//--------------------SERVO ONE--------------------//
void servoOne()
{
servoOne.write(70);
delay(10);
while(piso>0)
{
int x = piso;
while(x>0)
{
servoOne.write(170);
delay(200);
servoOne.write(40);
delay(200);
x--;
}
}
}
It occurs as it clashes between servoOne in Servo servoOne; and void servoOne(). Please replace servoOne in void servoOne() by some other name.
(don't forget to replace the function name in function call by your new function name)

Mapping a servo value (0-180) into (0-9000)

Currently I'm controlling my BLDC motor using a keypad, keying in the servo value (0-180). But my supervisor needs me to control it using a value between 0-9000 and not 0-180. I have been learning about the map() function. Somehow I don't quite understand and I'm currently stuck trying to incorporate it with my code. How do I map servo values of (0-180) to (0-9000)? Here is my code:
#include <Servo.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// Set the LCD I2C address
Servo myservo;
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
//row pinouts of the keypad (L1, L2, L3, L4)
byte colPins[COLS] = {5, 4, 3};
//column pinouts of the keypad (R1, R2, R3)
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// STATE CONDITION FOR MAIN LOOP
enum { enter_values, spin , finish } systemstate;
//FOR MOTORSPIN
unsigned long previousMillis = 0;
long interval = 1000;
// RPM MEASUREMENT
const int dataIN = 2; //IR sensor INPUT
unsigned long prevmillis; // To store time
unsigned long duration; // To store time difference
unsigned long lcdrefresh; // To store time for lcd to refresh
int rpm; // RPM value
boolean currentstate; // Current state of IR input scan
boolean prevstate; // State of IR sensor in previous scan
// DECLARE
int stage1speed , stage1time , stage2speed , stage2time , stage3speed , stage3time ;
void setup() {
Serial.begin(9600);
lcd.begin(20, 4);
myservo.attach(11);
systemstate = enter_values; // set up the starting state
pinMode(dataIN, INPUT);
prevmillis = 0;
prevstate = LOW;
lcd.setCursor(4, 1);
lcd.print("SPIN COATER");
lcd.setCursor(6, 2);
lcd.print("MACHINE");
delay(5000);
lcd.clear();
lcd.setCursor(3, 1);
lcd.print("S = speed(sv)");
lcd.setCursor(3, 2);
lcd.print("T = time(sec)");
delay(5000);
lcd.clear();
lcd.setCursor(3, 1);
lcd.print("Range of Speed");
lcd.setCursor(3, 2);
lcd.print("0-180 sv");
delay(5000);
lcd.clear();
}
//FUNCTION FOR KEY IN SPEED AND TIME
void enter_speed_time() {
lcd.setCursor(0, 0);
lcd.print("S=");
lcd.setCursor(0, 1);
lcd.print("T=");
lcd.setCursor(0, 2);
lcd.print("S=");
lcd.setCursor(0, 3);
lcd.print("T=");
lcd.setCursor(10, 0);
lcd.print("S=");
lcd.setCursor(10, 1);
lcd.print("T=");
lcd.setCursor(10, 2);
lcd.print("RPM");
stage1speed = getTheNumber();
lcd.setCursor(2, 0);
lcd.print(stage1speed);
Serial.print(stage1speed);
lcd.print("sv");
stage1time = getTheNumber();
lcd.setCursor(2, 1);
lcd.print(stage1time);
Serial.print(stage1time);
lcd.print("sec");
stage2speed = getTheNumber();
lcd.setCursor(2, 2);
lcd.print(stage2speed);
Serial.print(stage2speed);
lcd.print("sv");
stage2time = getTheNumber();
lcd.setCursor(2, 3);
lcd.print(stage2time);
Serial.print(stage2time);
lcd.print("sec");
stage3speed = getTheNumber();
lcd.setCursor(12, 0);
lcd.print(stage3speed);
Serial.print(stage3speed);
lcd.print("sv");
stage3time = getTheNumber();
lcd.setCursor(12, 1);
lcd.print(stage3time);
Serial.print(stage3time);
lcd.print("sec");
}
// FUNCTION TO GET NUMBERS FROM 4X3 MATRIC KEYPAD
int getTheNumber() {
char buffer[4];
int i = 0;
while (1) {
char key = keypad.getKey();
if ('0' <= key && key <= '9' && i < 3) {
// If it's a number AND we have space left, add to our string
buffer[i] = key;
i++;
} else if ('#' == key && i > 0) {
// If it's a * or #, end
// Null terminate
buffer[i] = 0;
int value = atoi(buffer); // Convert to an integer
break;
}
}
return atoi(buffer);
}
// FUNCTION FOR RPM MEASUREMENT
void rpmMeasure() {
// RPM Measurement
currentstate = digitalRead(dataIN); // Read IR sensor state
if (prevstate != currentstate) {
// If there is change in input
if (currentstate == HIGH) {
// If input only changes from LOW to HIGH
duration = (micros() - prevmillis); // Time difference between revolution in microsecond
rpm = (60000000 / duration); // rpm = (1/ time millis)*1000*1000*60;
prevmillis = micros(); // store time for next revolution calculation
}
}
prevstate = currentstate; // store this scan (prev scan) data for next scan
lcd.setCursor(10, 3);
lcd.print(rpm);
}
// FUNCTION FOR MOTOR SPINNING ACCORDING TO TIME AND SPEED
void motorspin() {
char key = keypad.getKey();
unsigned long currentMillis = millis();
int idleValue = 0;
static enum { IDLE , STAGE0, STAGE1, STAGE2, STAGE3 } spinningstate = IDLE;
switch (spinningstate) {
case IDLE:
if (key == '*') {
Serial.print(key);
spinningstate = STAGE0;
}
break;
case STAGE0:
myservo.write(stage1speed);
Serial.print(stage1speed);
previousMillis = currentMillis;
spinningstate = STAGE1;
break;
case STAGE1:
if (currentMillis - previousMillis >= stage1time * interval) {
myservo.write(stage2speed);
Serial.print(stage2speed);
previousMillis = currentMillis;
spinningstate = STAGE2;
}
break;
case STAGE2:
if (currentMillis - previousMillis >= stage2time * interval) {
myservo.write(stage3speed);
Serial.print(stage3speed);
previousMillis = currentMillis;
spinningstate = STAGE3;
}
break;
case STAGE3:
if (currentMillis - previousMillis >= stage3time * interval) {
myservo.write(idleValue);
Serial.print(idleValue);
spinningstate = IDLE;
}
break;
default:
spinningstate = IDLE;
break;
}
}
// MAIN LOOP
void loop() {
char key = keypad.getKey();
switch (systemstate) {
case enter_values:
enter_speed_time();
systemstate = spin;
break;
case spin:
rpmMeasure();
motorspin();
if (key == '#') {
Serial.print(key);
systemstate = finish;
}
break;
case finish:
lcd.clear();
delay(1000);
systemstate = enter_values;
break;
default:
systemstate = enter_values;
}
delay(1);
}
to convert value from 0-180 to 0-9000
map(value,0,180,0,9000)
to convert from 0-9000 to 0-180
map(value,0,9000,0,180)

Arduino Calculator (Multiple Button Pressing)

We're currently making a 4x3 calculator using Arduino and LCD. We're lacking buttons so instead of one button per operation, there's only one button for all operations. So far, it only does addition. How do you do the thing wherein if I pressed the OPERATION button once, it does addition, if twice, subtraction, etc.
#include <Keypad.h>
#include <LiquidCrystal.h> //import lcd library
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //lcd pins
//LiquidCrystal lcd(5,4,3,2,1,0);
const byte ROWS = 4; // four rows
const byte COLS = 3;
//define the keymap
char keys [ROWS] [COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'+', '0', '='}
};
byte rowPins[ROWS] = {
9 ,8 ,7 ,6}; //connect keypad ROW1, ROW2, ROW3, ROW4 to these arduino pins
byte colPins[COLS] = {
13, 10, 1};
//create the keypad
Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
//variables declaration
boolean valOnePresent = false;
boolean next = false;
boolean final = false;
String num1, num2;
int ans;
char op;
void setup(){
lcd.begin(16,2);
lcd.setCursor(2,0);
lcd.print("Calculator");
delay(2500);
lcd.clear(); //clears the LCD screen and positions the cursor in the upper-left corner.
}
void loop(){
char key = myKeypad.getKey();
if (key != NO_KEY && (key=='1'||key=='2'||key=='3'||key=='4'||key=='5'||key=='6'||key=='7'||key=='8'||key=='9'||key=='0')){
if (valOnePresent != true){
num1 = num1 + key;
int numLength = num1.length();
lcd.setCursor(15 - numLength, 0); //to adjust one whitespace for operator
lcd.print(num1);
}
else {
num2 = num2 + key;
int numLength = num2.length();
lcd.setCursor(15 - numLength, 1);
lcd.print(num2);
final = true;
}
}
else if (valOnePresent == false && key != NO_KEY && (key == '/' || key == '*' || key == '-' || key == '+')){
if (valOnePresent == false){
valOnePresent = true;
op = key;
lcd.setCursor(15,0);
lcd.print(op);
}
}
else if (final == true && key != NO_KEY && key == '='){
if (op == '+')
{
ans = num1.toInt() + num2.toInt();
}
else if (op == '='){
ans = num1.toInt() + num2.toInt();
}
/* else if (op == '+')
{
answ = num1.toInt() - num2.toInt();
}
*/
lcd.clear();
lcd.setCursor(15,0);
lcd.autoscroll();
lcd.print(ans);
lcd.noAutoscroll();
}
}
You could use an array in order to accomplish this. By implementing a while loop with a small delay you can keep iterating through the positions in the array every time the button is pushed until the array times out. Here's an example of some could you could use to implement it.
char ops [4] = {'+','-','/','*'};
int del = 2500;
int strt = millis();
int location = 0;
while (millis() - strt < del) {
key = myKeypad.getkey();
if (key == '+') {
if (loc == 3) {
location = 0;
}
else {
location += 1;
}
strt = millis();
}
}
op = ops(location);

Resources