Buongiorno a tutti e a tutte,
Mi sono scontrato contro un problema che credo sia alquanto comune alle scuole superiori e mi chiedevo come potessi risolverlo. In sostanza il problema è questo: "come si può calcolare più velocemente una misura con il suo errore (incertezza) assoluto (a)?". Mi sono allora risposto da solo pensando di usufruire delle infinite potenzialità di Arduino. Ho iniziato allora provando a scrivere un codice tale che inserendo i valori dalla porta seriale mi riuscisse a fare tutti i calcoli e restituendomi i valori tramite un display. Raggiunto tale traguardo mi sono posto un obiettivo più alto: evitare di usare la porta seriale in modo da potermi portare la "calcolatrice" in giro senza dover utilizzare il computer (in tal caso basterebbe una tabella excel). Per Natale il gentilissimo babbo Natale mi ha regalato un tastierino a matrice 4x4 (questo), ma non so come utilizzarlo perchè nelle "istruzioni" è presente solo una spiegazione su come estrarre un valore singolo alla volta, ma a me serve un sistema che mi possa permettere di scrivere un valore anche con cifre decimali. Ho allora tentato di adattare il codice che utilizzavo per leggere dalla porta seriale al tastierino, ma non ci sono riuscito. Il codice per leggere i dati dalla porta seriale è il seguente:
if(Serial.available()){ //inserisce i caratteri inviati sul monitor seriale dentro la variabile di tipo "char"
stringa = "";
do{
if(Serial.available()){
c=Serial.read();
if(c != '\n')
stringa+=c;
}
}while(c != '\n');
Il problema sta nel fatto che non ho un Serial.available()
per il tastierino...
Inoltre le variabili float tengono i valori decimali fino ai centesimi, ma nei calcoli scientifici si può arrivare ad avere anche più di 5-6 cifre decimali...
Riassumendo i problemi sono:
- Permettere il funzionamento del tastierino 4x4 su Arduino;
- Trovare una modalità che permetta di compiere calcoli e immagazzinare dati in variabili con numeri decimali oltre le 5-6 cifre decimali;
- Ottimizzare lo sketch se possibile;
- Eventualmente salvare i calcoli su una schedina microSD;
Il codice al momento è il seguente:
#include <Keypad.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define COLS 4
#define ROWS 4
char KEYS[ROWS][COLS]={
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '-', '#', 'D'}
};
byte colPIN[COLS] = { 31, 33, 35, 37 };
byte rowPIN[ROWS] = { 23, 25, 27, 29 };
char pressedTaster;
Keypad tastierino = Keypad(makeKeymap(KEYS), rowPIN, colPIN, ROWS, COLS);
char c;
String stringa;
struct incertezza{
float x;
float Dx;
float y;
float Dy;
float G;
float DG;
byte operazione;
byte stato;
float elevato;
};
struct incertezza inc;
void setup() {
lcd.begin(16,2);
lcd.clear();
lcd.setCursor(0, 0);
Serial.begin(9600);
inc.stato = 0;
}
void loop() {
Serial.println(stringa);
if(inc.stato == 0){
lcd.setCursor(0,0);
lcd.print("Calcolatrice");
lcd.setCursor(0,1);
lcd.print("con errore");
delay(500);
inc.stato = 1;
}else if(inc.stato == 1){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("misura 1:");
lcd.setCursor(10,0);
lcd.print(stringa);
if(Serial.available()){
stringa = "";
do{
c=tastierino.getKey();
if(c != "A" || c != "B" || c != "C" || c != "D"){
stringa+=c;
}
}while(c != "A" || c != "B" || c != "C" || c != "D");
}
inc.x = stringa.toFloat();
if(inc.x != 0){
inc.stato = 2;
lcd.print(inc.x);
stringa = "";
delay(1500);
}
}else if(inc.stato == 2){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("errore misura 1:");
lcd.setCursor(0,1);
stringa = "";
do{
c=tastierino.getKey();
if(c != "A" || c != "B" || c != "C" || c != "D"){
stringa+=c;
}
}while(c != "A" || c != "B" || c != "C" || c != "D");
inc.Dx = stringa.toFloat();
if(inc.Dx != 0){
inc.stato = 3;
lcd.print(inc.Dx);
stringa = "";
delay(1500);
}
}else if(inc.stato == 3){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("misura 2 o ^x:");
lcd.setCursor(10,0);
lcd.print(stringa);
if(Serial.available()){
stringa = "";
do{
c=tastierino.getKey();
if(c != "A" || c != "B" || c != "C" || c != "D"){
stringa+=c;
}
}while(c != "A" || c != "B" || c != "C" || c != "D");
}
inc.y = stringa.toFloat();
if(inc.y != 0){
inc.stato = 4;
lcd.print(inc.y);
stringa = "";
delay(1500);
}
}else if(inc.stato == 4){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("errore misura 2:");
lcd.setCursor(0,1);
if(Serial.available()){
stringa = "";
}
inc.Dy = stringa.toFloat();
if(inc.Dy != 0){
inc.stato = 5;
lcd.print(inc.Dy);
stringa = "";
delay(1500);
}
}else if(inc.stato == 5){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("operazione:");
lcd.setCursor(0,1);
if(Serial.available()){
stringa = "";
do{
c=tastierino.getKey();
if(c != "A" || c != "B" || c != "C" || c != "D"){
stringa+=c;
}
}while(c != "A" || c != "B" || c != "C" || c != "D");
}
if(stringa == "+"){
inc.G = inc.x+inc.y;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("risultato:");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("G=");
lcd.setCursor(4,0);
lcd.print(inc.G);
inc.DG = inc.Dx+inc.Dy;
lcd.setCursor(0,1);
lcd.print("DG=");
lcd.setCursor(4,1);
lcd.print(inc.DG);
while(1);
}else if(stringa == "-"){
inc.G = inc.x-inc.y;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("risultato:");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("G=");
lcd.setCursor(4,0);
lcd.print(inc.G);
inc.DG = inc.Dx+inc.Dy;
lcd.setCursor(0,1);
lcd.print("DG=");
lcd.setCursor(4,1);
lcd.print(inc.DG);
while(1);
}else if(stringa == "*"){
inc.G = inc.x*inc.y;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("risultato:");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("G=");
lcd.setCursor(4,0);
lcd.print(inc.G);
inc.DG = inc.G*((inc.Dx/inc.x)+(inc.Dy/inc.y));
lcd.setCursor(0,1);
lcd.print("DG=");
lcd.setCursor(4,1);
lcd.print(inc.DG);
while(1);
}else if(stringa == "/"){
inc.G = inc.x/inc.y;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("risultato:");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("G=");
lcd.setCursor(4,0);
lcd.print(inc.G);
inc.DG = inc.G*((inc.Dx/inc.x)+(inc.Dy/inc.y));
lcd.setCursor(0,1);
lcd.print("DG=");
lcd.setCursor(4,1);
lcd.print(inc.DG);
while(1);
}else if(stringa == "^"){
for(int i; i=1; i++){
inc.elevato = inc.elevato*inc.x;
}
inc.G = inc.x*inc.x;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("risultato:");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("G=");
lcd.setCursor(4,0);
lcd.print(inc.G);
inc.DG = inc.y*(inc.Dx/inc.x)*inc.elevato;
lcd.setCursor(0,1);
lcd.print("DG=");
lcd.setCursor(4,1);
lcd.print(inc.DG);
while(1);
}
}
delay(1000);
}