Buongiorno.
Io sinceramente non mi considero ne' un principiante ne' un esperto.
Ma vabbè andiamo al problema:
Io ho una tastiera PS/2, e vorrei interfacciarla con arduino.
Il mio scopo è che quando digito una parola, vorrei che se avessi scritto una parola (esempio "help") allora fà una determinata cosa.
Tipo una specie di terminale
ecco il codice:
#include <PS2Keyboard.h>
//Dove sta' comm = comando
const int DataPin = 4;
const int IRQpin = 3;
String comm = "";
PS2Keyboard keyboard;
void setup() {
delay(1000);
Serial.begin(9600);
while(!Serial.available);
keyboard.begin(DataPin, IRQpin);
Serial.println("Keyboard String Test:");
}
void loop() {
if (keyboard.available()) {
char c = keyboard.read();
comm = comm + c;
if (c == PS2_ENTER) {
//help è un esempio, può essere qualsiasi parola
if(comm == "help"){
Serial.println("hai digitato help");
else{
Serial.println("non hai digitato help");
}
}
} else if (c == PS2_TAB) {
Serial.print("[Tab]");
} else if (c == PS2_ESC) {
Serial.print("[ESC]");
} else if (c == PS2_PAGEDOWN) {
Serial.print("[PgDn]");
} else if (c == PS2_PAGEUP) {
Serial.print("[PgUp]");
} else if (c == PS2_LEFTARROW) {
Serial.print("[Left]");
} else if (c == PS2_RIGHTARROW) {
Serial.print("[Right]");
} else if (c == PS2_UPARROW) {
Serial.print("[Up]");
} else if (c == PS2_DOWNARROW) {
Serial.print("[Down]");
} else if (c == PS2_DELETE) {
Serial.print("[Del]");
} else {
Serial.print(c);
}
}
}
Il problema sta' che quando digito il comando "help" al programma, mi scrive sul display "non hai digitato help".
Credemi, ho cercato su google ma niente. non ho trovato nessun problema simile a questo.
Grazie in anticipo per le risposte
Buonasera,
essendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), ti chiedo cortesemente di presentartiIN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.
Guglielmo
P.S.: Qui una serie di link utili, NON necessariamente inerenti alla tua domanda: - serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections - pinout delle varie schede by xxxPighi: Pinout - link generali utili: Link Utili
SukkoPera:
E ripassati la differenza tra = e == in C.
Scusatemi.
Vi spiego: Stavo facendo una copia del codice(per publicarlo in questo Thread), quando Per errore, ho inserito 1 = invece che == .
il codice originale è con 2 ==.
Tu fai il test "if(comm == "help")" giustamente dentro un altro if, quello relativo a "if (c == PS2_ENTER)", ma, dato che tu ogni volta sommi il carattere ricevuto a 'comm', quando premi ENTER dentro a 'comm' ci finirà anche il valore di PS2_ENTER e quindi 'comm' NON potrà mai essere uguale a "help"
Ok, ho capito il concetto. Quindi mi stai dicendo che dovrei fare 2 cose:
rimuovere quel if(c == PS2_ENTER) (cosa un po' insensata poichè uscirebbe "non hai risposto help" fino a che non scrivi completamente h-e-l-p tasto per tasto)
Oppure una cosa più sensata: inserire in quel if una cosa del genere:
if(comm == PS2_ENTER && "help")
Sto supponendo , non credo che funzionerà al 100%
[Extra ] Creare una variabile apparte per non creare conflitto, come stà succedendo a me
Oppure semplicemente, alla ricezione del PS2_ENTER, mettere una flag a TRUE e nel loop() verificare se tale flag è TRUE e quando accade fare il controllo sul contenuto di 'comm' ... rimettendola poi a FALSE in attesa del prossimo PS2_ENTER
Allora, ho provato il mio modo e il tuo.
Iniziamo dal tuo:
Il codice modificato è questo:
#include <LiquidCrystal.h>
#include <PS2Keyboard.h>
//Dove sta' comm = comando
const int DataPin = 4;
const int IRQpin = 3;
String comm = "";
bool isEnter = false;
char c;
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
PS2Keyboard keyboard;
void setup() {
lcd.begin(24, 2);
delay(1000);
keyboard.begin(DataPin, IRQpin);
lcd.print("OK:");
}
void loop() {
if (isEnter == true) {
if (comm == "help") {
lcd.clear();
lcd.print("hai digitato help");
delay(3000);
lcd.clear();
isEnter = false;
} else {
lcd.clear();
lcd.print("non hai digitato help");
delay(3000);
isEnter = false;
lcd.clear();
}
} else if (keyboard.available()) {
c = keyboard.read();
comm = comm + c;
if (c == PS2_ENTER) {
isEnter = true;
}
else {
lcd.print(c);
}
}
}
ho inserito un lcd per testare così..
Il risultato? Lo stesso di quello all'inizio. : :
da' negativo.
Non mi sono arreso, così ho provato a modo mio
ecco il codice a modo mio:
#include <LiquidCrystal.h>
#include <PS2Keyboard.h>
//Dove sta' comm = comando
const int DataPin = 4;
const int IRQpin = 3;
String comm = "";
char chrSpecial;
bool isEnter = false;
char c;
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
PS2Keyboard keyboard;
void setup() {
lcd.begin(24, 2);
delay(1000);
keyboard.begin(DataPin, IRQpin);
lcd.print("OK:");
}
void loop() {
if (isEnter == true) {
if (comm == "help") {
lcd.clear();
lcd.print("hai digitato help");
delay(3000);
lcd.clear();
isEnter = false;
} else {
lcd.clear();
lcd.print("non hai digitato help");
delay(3000);
isEnter = false;
lcd.clear();
}
} else if (keyboard.available()) {
c = keyboard.read();
chrSpecial = keyboard.read();
comm = comm + c;
if (chrSpecial == PS2_ENTER) {
isEnter = true;
}
else {
lcd.print(c);
}
}
}
Il cambiamento stà nel aggiungere la famosa variabile chrSpecial nel tuo codice, ma ha avuto una strana reazione il display, ossia mi scriveva un carattere completamente pieno
Perché comunque tu, anche quando leggi PS2_ENTER lo metti dentro a 'comm' ... Tu, l'insersione in 'comm' la devi fare SOLO per i caratteri che veramente vuoi che ci vadano, quindi, prima verifichi COSA hai ricevuto e poi decidi se metter o meno in 'comm' in funzione dei caratteri che TU ammetti
Si, ma io ho poi aggiunto nel secondo codice la variabile "chrSpecial" che non ha nessun legame e soprattutto non va in conflitto con la varibile "c"
Simone_04:
Il cambiamento stà nel aggiungere la famosa variabile chrSpecial nel tuo codice, ma ha avuto una strana reazione il display, ossia mi scriveva un carattere completamente pieno
P.S. Poi domani faccio un test sulla seriale e vedo cosa esce..
Secondo me continui a seguire una logica contorta; linearmente potresti fare:
leggo la tastiera
controllo se è un carattere di quelli da memorizzare (es. spazio, 0..9, A..Z, a..z) ...
2.1 SI, lo metto in 'comm'
2.2 NO, esamino se è uno dei vari caratteri speciali che gestisco ed mi comporto di conseguenza
Ciao, alla fine ci sono riuscito!!!
ecco il codice:
#include <LiquidCrystal.h>
#include <PS2Keyboard.h>
//Dove sta' comm = comando
char caratteriSupportati[] = " abcdefghijklmnopqrstuvwxyz0123456789ABCEFGHIJKLMNOPQRSTUVWXYZ,;.:_+-*/=";
const int DataPin = 4;
const int IRQpin = 3;
String comm = "";
bool isEnter = false;
char c;
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
PS2Keyboard keyboard;
void setup() {
lcd.begin(24, 2);
delay(1000);
keyboard.begin(DataPin, IRQpin);
lcd.print("OK:");
}
void checkCommand() {
Serial.println("Sono dentro il CheckCommand");
if (comm == "help") {
lcd.clear();
Serial.println("Sono dentro il CheckCommand");
lcd.print("hai digitato help");
delay(41);
lcd.clear();
} else {
lcd.clear();
Serial.println("Sono dentro il CheckCommand");
lcd.print("non hai digitato help");
delay(41);
lcd.clear();
}
}
void loop() {
if (keyboard.available()) {
c = keyboard.read();
int ValMax = sizeof(caratteriSupportati);
for (int val = 0; val <= ValMax; val++) {
if (c == caratteriSupportati[val]) {
comm = comm + c;
lcd.print(c);
} else {
if (c == PS2_ENTER) {
Serial.println("Hai premuto enter");
lcd.clear();
checkCommand();
}
}
}
}
}
Se noti bene ho messo un delay molto basso, poichè io sono all'interno di un ciclo for che ha come conteggio massimo il valore dei caratteri, che non sarebbe altro che 72 mi pare..
comunque dato che moltiplicando 41*72 = 2952 ms, che sarebbero 3 secondi.
Grazie mille per aver risposto alle mie domande e anche di avermi sopportato
Se vuoi potersti pensare di ottimizzare qualche cosa ...
... ad esempio, la ricerca di un carattere nella stringa di caratteri validi, attualmente tu la fai con un ciclo for che esamina carattere per carattere.
Potersti invece usare la funzione strchr() che si trova in <string.h> che fa parte di AVR libc, libreria SEMPRE automaticamente inclusa dal IDE di Arduno, che è fatta apposta per cercare la presenza di un carattere all'interno di una stringa.
La sintassi è: "valoreDiRitorno = strchr(stringaDaCercare, carattereCercato);" dove valore di ritorno è ==NULL se NON ha trovato il carattere o != da NULL se lo ha trovato (in tal caso viene ritornato un puntatore a dove si trova il carattere nella stringa).
Quindi, con un semplice e veloce IF potresti sapere se il carattere è tra quelli validi o meno
Guglielmo
P.S.: Indipendentemente da tutto, studiati la AVR libc, è piena di utilissime e velocissime funzioni che spesso semplificano la vita
Ciao gpb01, ho fatto un buon uso del comando che mi hai consigliato di usare
Ecco il codice usando strchr() :
#include <LiquidCrystal.h>
#include <PS2Keyboard.h>
//Dove sta' comm = comando
char caratteriSupportati[] = " abcdefghijklmnopqrstuvwxyz0123456789ABCEFGHIJKLMNOPQRSTUVWXYZ,;.:_+-*/=";
const int DataPin = 4;
const int IRQpin = 3;
String comm = "";
char chrTrovato;
bool ResetComm = false;
char c;
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
PS2Keyboard keyboard;
void setup() {
lcd.begin(24, 2);
delay(1000);
keyboard.begin(DataPin, IRQpin);
int ValMax = sizeof(caratteriSupportati);
lcd.print("OK:");
}
void checkCommand() {
Serial.println("Sono dentro il CheckCommand");
if (comm == "help") {
lcd.clear();
Serial.println("hai digitato help");
lcd.print("hai digitato help");
delay(3000);
comm = "";
lcd.clear();
} else {
lcd.clear();
Serial.println("non hai digitato help");
lcd.print("non hai digitato help");
delay(3000);
comm = "";
lcd.clear();
}
}
void loop() {
Serial.println(comm);
if (keyboard.available()) {
c = keyboard.read();
chrTrovato = strchr(caratteriSupportati, c);
if (chrTrovato != NULL) {
comm = comm + c;
lcd.print(c);
} else {
if (c == PS2_ENTER) {
Serial.println("Hai premuto enter");
lcd.clear();
checkCommand();
}
}
}
}
Che inoltre ha risolto un altro problema: Non resettava il comando poichè ero all'interno di un ciclo for, ma grazie al comando sono riuscito a risolverlo..
Spero che sia di aiuto per quelli che come me abbiano riscontrato questo tipo di problema