/* ****************************
SERGIO PRENLELOUP
08-05-2025
versione v-101-48-080525
--------------------------------------------------------------------------
#include <Vcc.h>
const float minVcc = 0.0;
const float maxVcc = 5.0;
const float fix = 1.0103; // 4.9/5.0
Vcc vcc(fix);
void setup() {
Serial.begin(9600);
}
void loop() {
float v = vcc.Read_Volts();
Serial.print("V=");
Serial.print(v);
delay(1000);
float p = vcc.Read_Perc(minVcc, maxVcc);
Serial.print(" Perc=");
Serial.println(p);
delay(1000);
}
Nuovo sketch calcolatrice RPN NON programmabile.
Modalita Diretta == si eseguono le funzioni assegnate ai tasti in modo diretto,
in modo simile all'uso della
HP-41 alcuni tasti hanno la seconda funzione.
Si possono richiamare funzioni con XEQ nn che si potranno aggiungere
con programmazione in C
In questo modo anche questa calcolatrice è in pratica programmabile in "C"
Questa calcolatrice utilizza 48 tasti che sono composti
da tre tastierini da 16 tasti.
Si può realizzare anche con poche modifiche al listato una calcolatrice
a 32 tasti utilizzando 2 tastierini
Il display ha 4 linee
Mostrano i registri di catasta X, Y , Z
la riga più in basso serve solo come
visualizzatore del dato introdotto.
La calcolatrice si può utilizzare direttamente in modo simile alla HP-41
Utilizzando catasta e registri di memoria.
La catasta operativa.
X, Y, Z, T, U, lastX. ( in questa versione le lascio come variabili globali)
Ci sono 19 registri di memoria utente possono essere usati direttamente o
in programmi della funzione XEQnn (variabili globali).
********************************************************************************
****************************
Si possono aggiungere funzioni o programmi che utilizzino sia la
catasta e/o registri di memoria, questi programmi si possono
aggiungere alle funzioni esistenti; per richiamarli basterà eseguire XEQ nn (01-99).
//**********************************************************************************************************
FUNZIONI PROGAMMABILI E RELATIVI CODICI.
il codice è un byte ( quindi da 0 a 255)
MEMORIE & INDICI = da 01 a 19 alla pressione delle istruzioni:
STO; RCL; XEQ - si attiva una R nella sinistra del visore e si
introducono due cifre
01 per memoria 1 ... fino a 19 ( funzioni STO e RCL )
per la funzione XEQ da 01 fino a 40
-----------------------------------------------------------------
-------------------------------------------
CODICI TASTO FUNZIONI DIRETTE
49-1, 50-2, 51-3, 52-4, 53-5, 54-6, 55-7, 56-8, 57-9, 48-0,
46-punto, 43 +, 45 -, 44-*, 47-/, 90 ENTER
----------------------------------------------------------------------
--------------------------------------
58 SIN, 59 COS, 60 TAN, 61 ASIN , 62 ACOS, 63 ATAN, 64 LOG, 65 (2F),
66 STO, 67 PI, 68 SQRT, 69 FIX, 70 Y^x, 71 X^2, 72 LN, 73 R>P,
74 RCL, 75 EEX, 76 CHS, 77 HMS, 78 RAD, 79 1/X, 80 e^X, 81 P>R,
82 DEL, 83 X<>Y, 84 R\ 85 LASTX, 86 DISP, 87 CLST, 88 10^x, 89 XEQ
****************************************************************************
************************************
CON LA PRESSIONE DEL TASTO F2 (65) SI ATTIVANO LE SECONDE FUNZIONI
A QUESTI CODICI SI AGGIUNGE +50 OTTENENDO COSI CODICI DA 93 A 140 DISPONIBILI
PER SECONDE FUNZIONI
ATTIVATE SOLO TRE SECONDE FUNZIONI IN QUESTA VERSIONE
***********************************************************************
*****************************************
HARDWARE UTILIZZATO
ARDUINO UNO
una tastiera composta dall'assemblaggio di 3 tastierini 4x4, ottenendo
così una tastiera 12 x 4 ( 48 tasti) 4 RIGHE X 12 COLONNE.
Ai tasti verranno assegnate 2 o più funzioni.
Display lcd 20x4 (I2C)
Possibilità di alimentazione a batteria.
*****************************************
*/
//***************************************
// librerie incluse
//---------------------------------------
// E' inclusa anche da sistema la <maht.h>
#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
#include <Keypad.h>
#include <Vcc.h> // libreria controllo carica batteria
//***************************************************
const byte righe = 4; // per keypad
const byte colonne = 12;
//***************************************************
//****************************************************
// codici tastierino per 48 tasti
//***********************************************
byte chiave [righe][colonne] =
{ {49, 50, 51, 43, 58, 59, 60, 61, 62, 63, 64, 65}, //
{52, 53, 54, 45, 66, 67, 68, 69, 70, 71, 72, 73}, //
{55, 56, 57, 44, 74, 75, 76, 77, 78, 79, 80, 81}, //
{90, 48, 46, 47, 82, 83, 84, 85, 86, 87, 88, 89}, //
};
//-----------------------------------------------------------------------------
// pin assegnati al tastierino per ARDUINO UNO
//-----------------------------------------------------------------------------
//byte pinrighe[righe] = {14, 15, 16, 17}; // pin analogici A0, A1, A2, A3
//byte pincolonne[colonne] = {13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2};
//-----------------------------------------------------------------------
// pin assegnati al tastierino per ATMEGA 2560
//--------------------------------------------------------------------------
byte pinrighe[righe] = {23, 25, 27, 29};
byte pincolonne[colonne] = {53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, 31};
//------------------------------------------------------------------------------
// ------------------------------------------------------------------------
// QUI SOTTO VARIABILI E COSTANTI
//
//*********************************************************************
const float minVcc = 0.0;
const float maxVcc = 5.0;
const float correzione = 4.8/5.0; // 1.0103; // 4.9/5.0
Vcc vcc(correzione);
byte key; // contiene il codice tasto premuto
byte codice = 0; // codice operativo calcolato a partire da key (codice asccii)
int poscifra = 0;// tiene conto delle cifre
boolean sciee = false; // true visualizza in notazione scientifica
boolean stato = false; // per la calcolatrice ( seconda funzione dei tasti)
boolean dirette = true; //funzioni_dirette
boolean seconde = false; //funzioni_F2
boolean reg = false; // registri memoria (STOnn- RCLnn)
//------------------------------------------------------------------------
boolean se = true; // per le funzion if
boolean xeq = true; // per inserimento codice in Xeq_nn
boolean uscitacalc = true; // per uscire da caLCOLATRICE si mette a false
//-------------------------------------------------------------------------
float numero; // usata nella sci
float k1 = 10000000;// numero massimo visualizzabile poi si passa in scie
float k0 = 0.00001; // numero decimale piu piccolo visualizzabile
// per l'inserimento dei numeri decimali
int pdec = 0; // punto decimale
int ndec = 0; // conta decimali
int fix = 4; //decimali di default
int numProg = 0; // indice numero programmi in XEQ
//*********************************************************************
// ******* V A R I A B I L I G L O B A L I ************************
//*********************************************************************
//*** registri catasta
float lastx = 0.0; // recupero del registro x
float regx = 0.0;
float regy = 0.0;
float regz = 0.0;
float regt = 0.0;
float regu = 0.0;
// registri speciali
float regxs = 0.0; // per visualizzare la parte decimale della notazione sci
int esponente = 0; // esponente nella scientifica
float visore = 0.0; // accumula i valori immessi
//********************************************************************
//*******************************************************************
// STRINGHE caratteri custom
//********************************************************************
String nomeProg = "";
//********************************************************************
// caratteri batteria carica - scarica
//********************************************************************
byte batteriaScarica[8] = {
0b01110,
0b10001,
0b10001,
0b10001,
0b11001,
0b11101,
0b11111,
0b11111
};
byte batteriaCarica[8] = {
0b01110,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111
};
//----------------------------
//***********************
// memorie utente
//***********************
//--------------------------
float mem1 = 0.0;
float mem2 = 0.0;
float mem3 = 0.0;
float mem4 = 0.0;
float mem5 = 0.0;
float mem6 = 0.0;
float mem7 = 0.0;
float mem8 = 0.0;
float mem9 = 0.0;
float mem10 = 0.0;
float mem11 = 0.0;
float mem12 = 0.0;
float mem13 = 0.0;
float mem14 = 0.0;
float mem15 = 0.0;
float mem16 = 0.0;
float mem17 = 0.0;
float mem18 = 0.0;
float mem19 = 0.0;
//***********************
// inizializza keypad e lcd
//--------------------------------------------------------------------------------
Keypad keypad = Keypad (makeKeymap(chiave), pinrighe, pincolonne, righe, colonne);
LiquidCrystal_PCF8574 lcd(0x27);
//--------------------------------------------------------------------------------
void setup()
{
Wire.begin();
Wire.beginTransmission(0x27);
lcd.begin(20, 4); // initialize the lcd
lcd.setBacklight(255);
// creazione nuovi caratteri
lcd.createChar(0, batteriaScarica);
lcd.createChar(1, batteriaCarica);
lcd.home();
lcd.clear();
lcd.setCursor(0, 1);
//lcd.print("1234567890123456");
lcd.print("v-506-48-080525"); // VERSIONE
lcd.setCursor(0, 2);
//lcd.print("1234567890123456");
lcd.print("Calcolatrice RPN");
delay (3000);
}
//-----------------------------------------------------------------------
// LOOP PRINCIPALE
//---------------------------------------------------------------------
void loop()
{
calcolatrice();
}
//**** END LOOP ******************************************************
//********************************************************************
//*******************************************************************
// ********** F U N Z I O N I **********
//*******************************************************************
void calcolatrice() // questa è un loop per utilizzare come calcolatrice
{
uscitacalc = false;
dirette = true;
while (uscitacalc == false)
{
aggiornadisplay(); // sub che aggiorna il display
tasto(); // attende pressione tasto
tastiFunzione(); // si controlla se funzioni dirette o seconde funzioni
if (dirette == true)funzioni();//funzioni dirette
if (seconde == true) // seconde funzioni 2F
{
codice = codice + 50;
seconde_Funzioni();
}
}
}
//***************** fine calcolatrice ******************************
// con questa si controlla la seconda funzione
// (2F 65) se premuto attiva se già attive disattiva
void tastiFunzione()
{
if ( codice == 65) // F2 seconde funzioni
{
if (seconde == true)
{ seconde = false;
dirette = true;
}
else
{
seconde = true;
dirette = false;
}
}
}
//-----------------------------------------------------------
// qui si controlla il codice
// del tasto premuto e si indirizza l'esecuzione
// della relativa funzione e quindi si ritorna.
// queste funzioni sono per l'uso diretto della calcolatrice
//------------------------------------------------------------
void funzioni()
{
if (pdec == 0) // si deve scegliere fra numeri e numeri decimali
{
if ((codice >= 48) && (codice <= 57 ))
{
impostanumero();
}
}
if (pdec == 1) // è stato premuto il punto decimali
{
if ((codice >= 48) && (codice <= 57 ))
{
impostanumerodec();
}
}
//------------------------------------------------------------------
if (codice == 90)// ENTER
{
nome_funzione(codice);
enter();
}
if (codice == 43)// somma
{
nome_funzione(codice);
if (visore != 0)enter();
somma();
}
if (codice == 44)// moltiplicazione
{
nome_funzione(codice);
if (visore != 0)enter();
moltiplicazione();
}
if (codice == 45) //sottrazione
{
nome_funzione(codice);
if (visore != 0)enter();
sottrazione();
}
if (codice == 46) // punto decimali
{
punto(); // con questa si pone a 1 la pdec
}
if (codice == 47) //divisione
{
nome_funzione(codice);
if (visore != 0)enter();
divisione();
}
//----------------------------------------
// dal 48 al 57 ci sono le cifre da 0 a 9
//----------------------------------------
if (codice == 58) // seno di x angolo in RADIANTI
{
nome_funzione(codice);
if (visore != 0)enter();
senox();
}
if (codice == 59)// coseno x angolo in x in RADIANTI
{
nome_funzione(codice);
if (visore != 0)enter();
cosenx();
}
if (codice == 60)//tangente x angolo in x in RADIANTI
{
nome_funzione(codice);
if (visore != 0)enter();
tangx();
}
if (codice == 61)// arco seno di x
{
nome_funzione(codice);
if (visore != 0)enter();
arcosen_x();
}
if (codice == 62)// arco coseno di x
{
nome_funzione(codice);
if (visore != 0)enter();
arcocos_x();
}
if (codice == 63)// arco tangente di x
{
nome_funzione(codice);
if (visore != 0)enter();
arcotan_x();
}
if (codice == 64)////Log10
{
nome_funzione(codice);
if (visore != 0)enter();
log10x();
}
//---------------------------------------
// codice 65 2F seconde funzioni
// al codice viene aggiunto +50
//-----------------------------------------
if (codice == 66)// STO n
{
nome_funzione(codice);
// impostareg();
if ((visore > 0) && (visore <= 19))
{
sto_n();
del();
}
}
//-----------------------------------------
if (codice == 67)// // PI GRECO
{
nome_funzione(codice);
if (visore != 0)enter();
pigreco();
}
if (codice == 68) //radice quadrata
{
nome_funzione(codice);
if (visore != 0)enter();
sqrtx();
}
if (codice == 69)//fix decimali
{
visfix();
}
if (codice == 70)// potenza eleva y alla x
{
nome_funzione(codice);
Ysux();
}
if (codice == 71)// quadrato di x
{
nome_funzione(codice);
if (visore != 0)enter();
xquadro();
}
if (codice == 72) // ln logaritmo naturale
{
nome_funzione(codice);
if (visore != 0)enter();
logN();
}
if (codice == 73)// da rettangolari a polari
{
nome_funzione(codice);
R_P ();
}
//-------------------------------------
if (codice == 74) //RCL n
{
nome_funzione(codice);
// impostareg();
if ((visore > 0) && (visore <= 19))
{
rcl_n();
del();
}
}
//--------------------------------------
if (codice == 75)//EEX
{
nome_funzione(codice);
inputsci();
}
if (codice == 76)// CHS cambio segno (moltiplica x per -1
{
nome_funzione(codice);
cambiasegno(); // CHS
}
if (codice == 77)// converte da radianti in sessagesimali
{
nome_funzione(codice);
if (visore != 0)enter();
radHMS();
}
if (codice == 78)// da gradi sessagesimali a radianti
{
nome_funzione(codice);
if (visore != 0)enter();
HMSrad();
}
if (codice == 79) // 1/x
{
nome_funzione(codice);
if (visore != 0)enter();
unosux();
}
if (codice == 80) // e alla x exp(x)
{
nome_funzione(codice);
if (visore != 0)enter();
expX ();
}
if (codice == 81)
{
nome_funzione(codice);
P_R(); // da polari a rettangolari p>=0 e alfa >=0 e <= pi/2
}
if (codice == 82)//cancella carattere
{
del();
}
if (codice == 83)// x<>y scambio x con y
{
nome_funzione(codice);
scambio();
}
if (codice == 84) // R! scorre catasta giù
{
nome_funzione(codice);
ruota();
}
if (codice == 85)//Lastx ( recupera x )
{
nome_funzione(codice);
last_x();
}
if (codice == 86) // // 86 ruota SU catasta
{
nome_funzione(codice);
ruotaSU();
}
// CLST //
if (codice == 87)
{
nome_funzione(codice);
cancella(); //cancella catasta e visore
}
if (codice == 88) //10alla x
{
nome_funzione(codice);
if (visore != 0)enter();
po10x();
}
if (codice == 89) // Xeq esegue funzione da 1 a ...
{
nome_funzione(codice);
//impostareg();
if ((visore > 0) && (visore <= 40))
{
Xeq_nn();
del();
}
}
return;
}
//--------------------------------------------------
//end funzioni_dirette
//--------------------------------------------------
//***************************
//
// SECONDE FUNZIONI
//
//**************************-
void seconde_Funzioni()
{
if (codice == 112) //fact() // funzione fattoriale max 30
{
nome_funzione(codice);
if (visore != 0)enter();
fact();
seconde = false;
dirette = true;
}
if (codice == 113) //SQx_Y() radice x di Y
{
nome_funzione(codice);
if (visore != 0)enter();
SQx_Y();
seconde = false;
dirette = true;
}
if (codice == 114) // percento x%y
{
nome_funzione(codice);
if (visore != 0)enter();
percento();
seconde = false;
dirette = true;
}
// codice 115 2F
if (codice == 120) // FRC PARTE FRAZIONARIA DI X
{
nome_funzione(codice);
if (visore != 0)enter();
parteFRC();
seconde = false;
dirette = true;
}
if (codice == 121) // PARTE INTERA DI X
{
nome_funzione(codice);
if (visore != 0)enter();
parteINT();
seconde = false;
dirette = true;
}
if (codice == 122) // differenza percentuale
{
nome_funzione(codice);
if (visore != 0)enter();
percentoDi();
seconde = false;
dirette = true;
}
if (codice == 123) // MODULO PONE IN X IL RESTO DELLA DIVISIONE Y/X
{
nome_funzione(codice);
if (visore != 0)enter();
resto();
seconde = false;
dirette = true;
}
return;
//------------------------------------------------
}
void visualizzaBatt()
{
float p = vcc.Read_Perc(minVcc, maxVcc);
int Percento = p;
if (Percento <= 80){
lcd.setCursor(19,0);
lcd.write(byte(0));
}
else {
lcd.setCursor(19,0);
lcd.write(byte(1));
}
}
void visualizzaNome(String nomeFunzione)
{
lcd.setCursor(15, 3);
lcd.print(nomeFunzione);
delay(300); // TEMPO DOVE SI MOSTRA A SINISTRA IL NOME DELLA FUNZIONE
}
//--------------------------------------------
// ATTESA PRESSIONE TASTO
//****************************************************
void tasto()
{
key = 0; // azzera variabile tasto del tasterino e
//************* attende la pressione di un tasto sul tastierino
while (key == 0) // rimane qui fino alla pressione di un tasto
{
key = keypad.getKey();
codice = key;
}
}
//*********************************************************************
// AGGIORNA IL DISPLAY
//*********************************************************************
void aggiornadisplay()
{
//***************
// mostra display
//---------------
sciee = false;
// si esegue il controllo se visualizzare in notazione sci o con fix
float testx = regz;
if (testx < 0) testx = testx * -1;
if (testx > k1) sciee = true;
if (testx < k0) sciee = true;
if (testx == 0) sciee = false;
//**************************
lcd.clear();
visualizzaBatt();
lcd.setCursor(0, 0);
lcd.print("Z:");
lcd.setCursor(4, 0);
//---------------------------
if (sciee == true)
{ numero = regz;
sci(); // sub per notazione scientifica
lcd.print(regxs, 5);
lcd.setCursor(14, 0);
lcd.print (esponente);
}
else lcd.print(regz, fix);
//******************************
sciee = false;
testx = regy;
if (testx < 0) testx = testx * -1;
if (testx > k1) sciee = true;
if (testx < k0) sciee = true;
if (testx == 0) sciee = false;
//**************************
lcd.setCursor(0, 1);
lcd.print("Y:");
lcd.setCursor(4, 1);
//-------------------------
if (sciee == true)
{ numero = regy;
sci(); // sub per notazione scientifica
lcd.print(regxs, 5);
lcd.setCursor(14, 1);
lcd.print (esponente);
}
else lcd.print(regy, fix);
//******************************
sciee = false;
testx = regx;
if (testx < 0) testx = testx * -1;
if (testx > k1) sciee = true;
if (testx < k0) sciee = true;
if (testx == 0) sciee = false;
//**************************
lcd.setCursor(0, 2);
lcd.print("X:");
lcd.setCursor(4, 2);
if (sciee == true)
{ numero = regx;
lastx = regx;
sci(); // sub per notazione scientifica
lcd.print(regxs, 5);
lcd.setCursor(14, 2);
lcd.print (esponente);
}
else lcd.print(regx, fix); // visualizzazione normale
lcd.setCursor(0, 3);
if (dirette == true)
{lcd.print("1:");}
else {
lcd.print("2:");
}
if (visore != 0)
{
lcd.setCursor(4, 3);
lcd.print(visore, fix);
}
sciee = false;
}
//---------------------------------------------------------
// questa sub prepara "regxs" ed "esponente" per visualizzare in notazione sci
// ATTENZIONE regxs serve solo per la visualizzazione di numeri in notazione
// scientifica in abbinamento al registro "esponente"
// non viene utilizzato direttamente nei calcoli i due rappresentano comunque
// il contenuto di "regx" che deve essere utilizzato per il calcolo.
//**************************************************************
// PER NOTAZIONE SCIENTIFICA SI CALCOLA ESPONENTE
//*************************************************************
void sci()
{
int segno = 1;
int segnoe = 1;
esponente = 0;
// se il numero è negativo si trasforma in positivo
// ma si mette a -1 la variabile segno, ci servirà
// per ritornare a negativo dopo aver trovato
// il valore dell'esponte con la log10(numero)
if (numero < 0)
{
numero = numero * -1;
segno = -1;
}
double numlog = log10(numero); // si ottiene il logaritmo del numero
// N,xxxxx preleveremo la parte
// intera che rappresenta l'esponente
esponente = int( numlog); // adesso abbiamo il numero intero esponente
numero = numero * segno; // si ripristina il giusto segno
// si esegue il controllo se l'esponente è negativo e si
//esegue la stessa procedura fatta per il numero
if (esponente < 0)
{
esponente = esponente * -1;
segnoe = -1;
}
//-----------------------------------------------------------------------
// se segnoe è negativo il numero è molto piccolo
if (segnoe == -1)
{
regxs = numero * pow(10, esponente);
}
else regxs = numero / pow(10, esponente); //altrimenti numero molto grande
//------------------------------------------------------------------------
esponente = esponente * segnoe; // si ripristina il giusto segno
// all'esponente
}
// ************************************************************************
byte impostacodice() // imposta codice DEL TASTO BATTUTO
{
byte cod = 0;
tasto(); // inserisce nella variabile globale codice il
// tasto battuto ( da 43 a 90 )
tastiFunzione(); // lavora sulle boolean delle funzioni
// controlla lo stato delle funzioni e crea il codice effettivo
// aggiungendo al codice creato da tasto() 50,150 il +100 è per le alfa
// se il tasto premuto è un tasto funzione ritorna
if (codice == 65 )return cod;
// in questo modo ritorna cod = 0
// con queste si crea il codice effettivo considerando il tasto funzione relativo
if (dirette == true)cod = codice;//funzioni dirette
if (seconde == true) // deconde funzioni 2F
{ codice = codice + 50;
cod = codice;
}
//if (alfa == true)funzioni_alfa(); // tastiera alfa
// if (ardu == true)
// { codice = codice + 150; //funzioni arduino 3F
// cod = codice;
// }
return cod;
}
//---------------------------------------------------------------
void impostanumero()
{
poscifra = poscifra + 1;
if (poscifra < 9)
{ int cifra = codice - 48;
visore = visore * 10 + cifra;
}
else codice = 90;//enter
}
//****************************************************************
// questa variante migliora di poco la visualizzazione dei numeri decimali
// si scrive su visore il numero decimale
void impostanumerodec()
{
ndec = ndec + 1;
if (fix >= ndec)
{
float cifradec = (codice - 48.0);
if (ndec == 1)
{
visore = visore + (cifradec * 0.1);
}
if (ndec == 2)
{
visore = visore + (cifradec * 0.01);
}
if (ndec == 3)
{
visore = visore + (cifradec * 0.001);
}
if (ndec == 4)
{
visore = visore + (cifradec * 0.0001);
}
if (ndec == 5)
{
visore = visore + (cifradec * 0.00001);
}
}
else
{
codice = 90;
}
}
// //**************************************************
// FINE LISTATO
//**************************************************
//SCHEDA XEQ-STO-RCL PER LE FUNZIONI CON CHIAMTA nn
//---------------------------------------------------
//SCHEDA FUNZIONI DIRETTE E SECONDE
//---------------------------------------------------
//SCHEDA PROG PER I PROGRAMMI UTENTE CHIAMATI CON XEQnn
//------------------------------------------------------------------
// SCHEDA NOMI FUNZIONI CON STRINGHE VISUALIZZATE DEI NOMI FUNZIONI
//******************************************************************
//*******************************************
/----------------------------------------------------------
// FUNZIONI DIRETTE E SECONDE CON 2F
//----------------------------------------------------------
void senox()// SENO di x (con x in radianti)
{
lastx = regx;
regx = sin (regx);
}
void cosenx()// COSENO di x (con x in radianti)
{
lastx = regx;
regx = cos (regx);
}
void tangx() // TANGENTE di x (con x in radianti)
{
lastx = regx;
regx = tan (regx);
}
void unosux() // 1/X
{
if (regx == 0)return;
lastx = regx;
regx = ( 1 / regx);
}
void sqrtx() // RADICE QUADRATA DI X
{
lastx = regx;
regx = sqrt (regx);
}
void xquadro() // X ELEVATO AL QUADRATO
{
lastx = regx;
regx = regx * regx;
}
void pigreco() // PIGRECO
{
lastx = regx;
regu = regt;
regt = regz;
regz = regy;
regy = regx;
regx = PI;
}
void clx() // AZZERA IL REG X
{
lastx = regx;
regx = 0.0;
}
void log10x() // LOGARITMO DI X IN BASE 10
{
lastx = regx;
regx = log10(regx);
}
void logN() // LOGARITMO DI X IN BASE e
{
lastx = regx;
regx = log(regx);
}
void po10x()//10alla x
{
if (regx < 30)
{
lastx = regx;
regx = pow(10, regx);
}
}
void expX ()// exp e^x
{
lastx = regx;
regx = exp(regx);
}
void Ysux()// Y^x ( Y elevato alla X )
{
lastx = regx;
regx = pow (regy, regx);
}
void SQx_Y()// RADICE ENNESIMA DI Y (radice x di Y)
{
lastx = regx;
regx = pow (regy,(1/regx));
}
void HMSrad() // da gradi sessagesimali H.ms a Radianti
{
lastx = regx;
sess_sedec();
regx = regx * PI / 180.0;
}
void radHMS() //da radianti a gradi sessagesimali H.ms
{
lastx = regx;
regx = regx * 180.0 / PI;
sedec_sessa();
}
void somma()//43
{
lastx = regx;
regx = (regx + regy);
regy = regz;
regz = regt;
regt = regu;
del();
}
void sottrazione()//45
{
lastx = regx;
regx = (regy - regx);
regy = regz;
regz = regt;
regt = regu;
del();
}
// punto decimali
void punto()//46
{
pdec = 1;
ndec = 0;
codice = 0;
}
//cancella carattere dal visore
void del() //82
{
visore = 0;
poscifra = 0;
codice = 0;
pdec = 0;
ndec = 0;
}
void enter()//90 TASTO ENTER INTRODUCE IL VISORE in X e fa scorrere su
{
regu = regt;
regt = regz;
regz = regy;
regy = regx;
regx = visore;
del();
}
// moltiplicazione //44
void moltiplicazione()
{
lastx = regx;
regx = (regy * regx); // esegue la moltiplicazione
regy = regz;
regz = regt;
regt = regu;
del();
}
//divisione //47
void divisione()
{
if (regx == 0) return; //******* divisione per 0
lastx = regx; // prima salva in lastx il valore di x
regx = (regy / regx); // esegue la divisione
regy = regz;
regz = regt;
regt = regu;
del();
}
// clr // CLST //
void cancella() //cancella catasta e visore
{
regu = 0.0;
regt = 0.0;
regz = 0.0;
regy = 0.0;
regx = 0.0;
lastx = 0.0;
visore = 0.0;
poscifra = 0;
codice = 0;
pdec = 0;
ndec = 0;
}
void cancella_mem()// cancella memorie utente
{
mem1 = 0.0;
mem2 = 0.0;
mem3 = 0.0;
mem4 = 0.0;
mem5 = 0.0;
mem6 = 0.0;
mem7 = 0.0;
mem8 = 0.0;
mem9 = 0.0;
mem10 = 0.0;
mem11 = 0.0;
mem12 = 0.0;
mem13 = 0.0;
mem14 = 0.0;
mem15 = 0.0;
mem16 = 0.0;
mem17 = 0.0;
mem18 = 0.0;
mem19 = 0.0;
}
//Lastx
void last_x()//85 RECUPERA IL CONTENUTO DI X
{
regu = regt;
regt = regz;
regz = regy;
regy = regx;
regx = lastx;
}
// x<>y scambio
void scambio()//83 SCAMBIA I REGITRI X Y NELLA CATASTA
{
float scambio = regx;
regx = regy;
regy = scambio;
}
//ruota giu la catasta
void ruota()//84 RUOTA GIU' LA CATASTA
{
float ruota = regx;
regx = regy;
regy = regz;
regz = regt;
regt = regu;
regu = ruota;
}
// 86 ruota SU la catasta
void ruotaSU()
{
float ruota = regu;
regu = regt;
regt = regz;
regz = regy;
regy = regx;
regx = ruota;
}
//cambiosegno
void cambiasegno()//86 CAMBIA SEGNO AL REGISTRO X
{
lastx = regx; regx = regx * -1;
}
// FIX----- scelta numero decimali dopo il punto da 0 a 5
void visfix()//77
{ if (( visore < 0 ) || (visore > 5)) return;
else fix = visore;
}
void arcosen_x()// 61 ASIN ritorna angolo in x in RADIANTI
{
if ((regx < -1) || ( regx > 1)) return;
{
lastx = regx;
regx = asin (regx);
}
}
void arcocos_x()//62 ACOS ritorna angolo in x in RADIANTI
{
if ((regx < -1) || ( regx > 1)) return;
{
lastx = regx;
regx = acos (regx);
}
}
void arcotan_x()//63 ATAN ritorna angolo in x in RADIANTI
{
lastx = regx;
regx = atan (regx);
}
// converte x da sessagesimale a sessadecimale
// solo il registro x della catasta viene utilizzato
void sess_sedec() // FUNZIONE
{
lastx = regx;
float a = regx;
int b = int(a); // i gradi
float c = (a - b) * 100;
int d = int(c);
float pri = d / 60.0; // primi
float sec = (c - d) / 36.0; // i secondi
regx = (b + pri + sec);
}
// converte x da sessadecimali a sessagesimali
// solo il registro x della catasta viene utilizzato
void sedec_sessa() // FUNZIONE
{
lastx = regx;
float a = regx;
int b = int(a); // i gradi
float c = (a - b) * 60;
int d = int(c); // i primi
float pri = d / 100.0;
float sec = (c - d) * 6 / 1000.0; // i secondi
regx = (b + pri + sec);
}
// da polari a rettangolari inserire in x l'angolo alfa
// in gradi RADIANTI
// inserire in y la magnitudine
// restituisce le cordinate in x e y
void P_R()
{
double magni = regy;
double alfa = (regx);
if (magni < 0)return;
if (alfa > (2 * PI))return;
if (alfa < 0 )return;
regx = magni * cos(alfa);
regy = magni * sin(alfa);
}
// da rettangolari a polari inserire in x la coordinata Xp
ed in y la coordinata Yp
// restituisce in y la distanza
// e restituisce in x angolo in RADIANTI
//
void R_P()
{
double alfa = 0;
double magni = sqrt((regx * regx) + (regy * regy));
alfa = atan2(regy, regx);
regx = alfa;
regy = magni;
}
// questa sub serve ad inserire un numero molto grande o molto piccolo
// in catasta inserendo in y il valore n.nnnnn ed in x l'esponente base 10
void inputsci()
{
double numero = regy;
double esp = regx;
regx = numero * pow(10, esp);
regxs = regx;
esponente = esp;
sciee = true;
}
void fact() // funzione fattoriale max 30
{
int numero = regx;
double fact = 1.0;
regx = fact;
if ((numero < 1) || (numero > 31)) return;
else
{
for ( int i = numero; i > 1; i--)
{
fact = fact * i;
}
regx = fact;
}
}
// end fact
void percento()
{
lastx = regx;
regx = (regx * regy / 100);
}
void percentoDi()
{
if ( regy == 0) return;
lastx = regx;
regx = (( regx - regy)* 100)/ regy;
}
void parteFRC()
{
lastx = regx;
int parteint = (int) regx;
regx = (regx - parteint);
}
void parteINT()
{
lastx = regx;
regx = (int) regx;
}
void resto()
{
lastx = regx;
int parteint = (int)(regy/regx);
int re = regy - (parteint * regx);
regx = re;
}
//***************
// -----------------------------------------------------------------
// NOME FUNZIONE
// questa funzione ritorna una stringa con il nome della funzione
// relativa al codice passato, che sarà visualizzata
// a destra sul display per 300 ms.
//-------------------------------------------------------------------
String nome_funzione(byte codice)
{
String nomeFunzione = "";
if ((codice >= 48) && (codice <= 57 ))return nomeFunzione;// numeri
if ((codice >= 0 ) && (codice <= 42 ))nomeFunzione = (codice);// registri
if (codice == 46)return nomeFunzione;// punto decimale
//---------------------------------------------------------
if (codice == 43)nomeFunzione = "SOMMA";
if (codice == 44)nomeFunzione = "PER";
if (codice == 45)nomeFunzione = "MENO";
if (codice == 47)nomeFunzione = "DIV";
if (codice == 58)nomeFunzione = "SIN";// SENO
if (codice == 59)nomeFunzione = "COS";// COSENO
if (codice == 60)nomeFunzione = "TAN";// TANGENTE
if (codice == 61)nomeFunzione = "ASIN";// ARCOSENO DI X
if (codice == 62)nomeFunzione = "ACOS";// ARCOCOSENO DI X
if (codice == 63)nomeFunzione = "ATAN";// ARCOTANGENTE DI X
if (codice == 64)nomeFunzione = "LOG";// LOGARITMO BASE 10
if (codice == 65)return nomeFunzione;// seconda funzione
if (codice == 66)nomeFunzione = "STO";// STOnn INSERIMENTO IN MEMORIA nn
if (codice == 67)nomeFunzione = "PI";// PI GRECO
if (codice == 68)nomeFunzione = "SQRT";// SQRT
if (codice == 69)return nomeFunzione;// FIX fissa i decimali visibili
if (codice == 70)nomeFunzione = "Y^x";// Y ELEVATO A X
if (codice == 71)nomeFunzione = "X2";// X AL QUADRATO
if (codice == 72)nomeFunzione = "LN";// LOG N
if (codice == 73)nomeFunzione = "R>P";// DA RETTANGOLARI A POLARI
if (codice == 74)nomeFunzione = "RCL";// RCLnn RICHIAMA LA MEMORIA nn
if (codice == 75)nomeFunzione = "EEX";// EEX INSERIMENTO ESPONENTE
if (codice == 76)nomeFunzione = "CHS";// CAMBIO SEGNO
if (codice == 77)nomeFunzione = "HMS";// >HMS DA RADIANTI A GRADI/MINUTI/SECONDI
if (codice == 78)nomeFunzione = "RAD";// >RAD DA DECIMALI A RADIANTI
if (codice == 79)nomeFunzione = "1/X";// 1/X
if (codice == 80)nomeFunzione = "e^X";// e ALLA X
if (codice == 81)nomeFunzione = "P>R";// DA POLARI A RETTANGOLARI
if (codice == 82)nomeFunzione = "DEL";// DEL CANCELLA VISORE
if (codice == 83)nomeFunzione = "X<>Y";// X<>Y SCAMBIO X CON Y
if (codice == 84)nomeFunzione = "RGIU";// RGIU SPOSTA GIù LA CATASTA
if (codice == 85)nomeFunzione = "LASTX";// LASTX RICHIAMA IN IN X IL REGISTRO LASTX
if (codice == 86)nomeFunzione = "R_SU"; // RUOTA SU LA CATASTA
if (codice == 87)nomeFunzione = "CLST";// CANCELLA CATASTA E VISORE
if (codice == 88)nomeFunzione = "10^x ";// 10 ^x
if (codice == 89)nomeFunzione = "XEQ";// XEQ ESEGUE FUNZIONE O PROGRAMMA
if (codice == 90)nomeFunzione = "ENTER";
//*********************************************
// seconde funzioni + 50 da 93 a 140
//*********************************************
if (codice == 93)nomeFunzione = "093";// tasto piu
if (codice == 94)nomeFunzione = "094";// tasto per
if (codice == 95)nomeFunzione = "095";// tasto meno
if (codice == 96)nomeFunzione = "097";// tasto diviso
if (codice == 108)nomeFunzione = "108";//
if (codice == 109)nomeFunzione = "109";//
if (codice == 110)nomeFunzione = "110";//
if (codice == 111)nomeFunzione = "111";//
if (codice == 112)nomeFunzione = "FACT";// FATTORIALE DI X
if (codice == 113)nomeFunzione = "Rx-Y";// RADICE x DI Y
if (codice == 114)nomeFunzione = " % ";// PERCENTUALE x DI Y
if (codice == 115)nomeFunzione = "115";// 2F
if (codice == 116)nomeFunzione = "116";//
if (codice == 117)nomeFunzione = "117";//
if (codice == 118)nomeFunzione = "118";//
if (codice == 119)nomeFunzione = "119";//
if (codice == 120)nomeFunzione = "FRC";// PARTE FRAZIONARIA DI X
if (codice == 121)nomeFunzione = "INT";// PARTE INTERA DI X
if (codice == 122)nomeFunzione = "% DI";// DIFFERENZA PERCENTUALE FRA X ED Y
if (codice == 123)nomeFunzione = "MOD";// MODULO DIVISIONE Y MOD X IL RESTO è IN X
if (codice == 124)nomeFunzione = "124";//
if (codice == 125)nomeFunzione = "125";//
if (codice == 126)nomeFunzione = "126";//
if (codice == 127)nomeFunzione = "127";//
if (codice == 128)nomeFunzione = "128"; //
if (codice == 129)nomeFunzione = "129";//
if (codice == 130)nomeFunzione = "130";//
if (codice == 131)nomeFunzione = "131";//
if (codice == 132)nomeFunzione = "132";//
if (codice == 133)nomeFunzione = "133";//
if (codice == 134)nomeFunzione = "134";//
if (codice == 135)nomeFunzione = "135";//
if (codice == 136)nomeFunzione = "135";//
if (codice == 137)nomeFunzione = "137";//
if (codice == 138)nomeFunzione = "138";//
visualizzaNome(nomeFunzione);
return nomeFunzione;
}
//*****************************************************
//************************************************************
//
// In questa scheda PROG-DI-XEQnn
// ci sono i prorammi aggiuntivi
// che sono chiamati con XEQnn.
// Il primo è l'elenco dei programmi "catalog"
// fa una funzione simile alla catalog della HP dove mostra
// il numero da inserire nella XEQnn ed il nome del programma
// per eseguire questi programmi bisogna inserire
// nei registri e/o nelle memorie i valori richiesti.
// il programma viene eseguito ed nei registri si trovano i
// risultati nei registri della catasta e/o nelle memorie
//
// Se si vuole aggiungere un programma si
// dovrà modificare queste parti:
// 1) aggiungere in questa scheda il programma con suo nome
// 2) modificare in questa scheda il prog catalog aggiungendolo
// 3) modificare la scheda XEQ-STO-RCL nella parte relativa
// alla chiamata XEQnn inserendo nel ciclo case
// il nome del nuovo programma
//************************************************************
void catalog()
{
lcd.clear();
// se si aggiungono programmi aggiornare la lista qui sotto
for (int i = 1; i < 10; i++)
{
numProg = i;
if (i == 1)nomeProg = "LISTA PROGRAMMI";
if (i == 2)nomeProg = " TRI. CARNOT ";
if (i == 3)nomeProg = " PARALLELO RES ";
if (i == 4)nomeProg = "Triangolo Erone";
if (i == 5)nomeProg = " PARTITORE V ";
if (i == 6)nomeProg = " SCORPORO IVA ";
if (i == 7)nomeProg = "INPUT-OUT-PROG ";
if (i == 8)nomeProg = "RAD -> CENTESI ";
if (i == 9)nomeProg = "CENTES. -> RAD ";
lcd.setCursor(0, 0);
lcd.print(numProg);
lcd.setCursor(4, 0);
lcd.print(nomeProg);
delay (1800);
lcd.clear();
}
//lcd.clear();
}
//**********************************************************************************************
//
// 1° ESEMPIO PROGRAMMA CALCOLO TRIANGOLO CON CARNOT
//
void carnot() // funzione 02 ****
{
// angolo in x in RADIANTI
double latoa = regz; // uno dei lati conosciuti
double latob = regy; // il secondo lato conosciuto
double angolo = regx;// angolo compreso fra i due lati
// si cerca il terzo lato
// gli angoli INPUT sono inseriti in RADIANTI
// gli angoli in OUT saranno in RADIANTI
//***********************************
// due lati ed angolo compreso
double latoc = sqrt(pow(latoa,2)+ pow(latob,2)-(2*latoa*latob)*cos(angolo));
regx = latoc; // in x troviamo il lato cercato opposto all'anglo compreso
regy = latob; // lato noto
regz = latoa; // lato noto
regt = angolo; // angolo noto in radianti
//**************************************************
} // fine carnot
void parallelo() // prog 03
{
//*************************************************************
// PARALLELO RESISTORI
//
// // r1 -r2
//*************************************************************
// si inseriscono in x ed in y i valori di due resistori.
//
// questo programma modifica tutto lo stak
// in uscita avremo in x la resistenza parallelo
//
//*****************************
double resp = 0;
resp = 1/ ((1/regx)+ (1/regy));
regx = resp;
regy = 0;
regz = 0;
regt = 0;
}
// fine parallelo
//******************************************************************
//************************************************************
// superficie triangolo con Erone
// noti i tre lati in x lato a, in y lato b, in z lato c
// restituisce in x la superficie, in y,z, t i lati a,b,c.
//*************************************************************
//
void erone() // fuzione 04 ****
{
double latoa = regx;
double latob = regy;
double latoc = regz;
if (latoa >= (latob+latoc)|| latob >= (latoc + latoa)|| latoc >=(latob+latoa)) return;
else {
double perimetro = latoa + latob + latoc;
double per2 = perimetro/2;
double super = sqrt(per2*((per2-latoa)*(per2-latob)*(per2-latoc)));
regx = super;
regy = latoa;
regz = latob;
regt = latoc;
}
}// fine erone
//*******************************************************
// partitore di tensione
//*******************************************************
void partitore() // funzione 05
{
//*****************************
//Vn= VIN(Rn/(R1 + R2 + R3)
double r1 = regy; // inserire valore R1 in omm
double r2 = regz; // inserire valore R2 in omm
double r3 = regt; // inserire valore R3 se non serve inserire 0
double vin = regx;// inserire Vin in Volt
double v1 = vin * ( r1 / ( r1+r2+r3));
double v2 = vin * ( r2 / ( r1+r2+r3));
double v3 = vin * ( r3 / ( r1+r2+r3));
regx = v1; // Volt in v1
regy = v2; // Volt in v2
regz = v3; // Volt in v3
regt = 0;
} // fine partitore
//*****************************************************************
// SCORPORO IVA impostare in Y l'aliquota
// impostare in X il totale compreso IVA
// in OUTPUT avremo:
// x = IVA, y = imponibile, z = il totale, t = aliquota.
// *****************************************************************
//
void sco_iva()// funzione 06 ****
{
//****************************************
double aliq = regy;
double total = regx;
double imponibile = (total*100)/(100+aliq);
//*****************************************
//output
regx = (total - imponibile); // IVA
regy = imponibile;
regz = total;
regt = aliq;
//*****************************************
} // fine scorporo iva
//----------------------------------------------------------------------------
void input_out_prog()
{
lcd.clear();
// lcd.print("01234567890123456789");
lcd.setCursor(0, 0);
lcd.print("Inserire i dati nei ");
lcd.setCursor(0, 1);
lcd.print("registri x,y,z,t ");
lcd.setCursor(0, 2);
lcd.print("angoli in RAD ");
lcd.setCursor(0, 3);
lcd.print("num poi tasto XEQ ");
tasto();
lcd.clear();
}
//******************************************
//--------------------------------------------------------------------------
// SCHEDA FUNZIONI CON INDICE .. STO - RCL - XEQ
//-----------------------------------------------------------------------
// IN QUESTA SCHEDA CI SONO TRE VOID CON LA STRUTTURA SWITCH - CASE
// CHE MEMORIZZANO ( con STO nn) o richiamano delle memorie ( con RCL nn)
// in questa scheda si trova anche la strurrura switch-case
// per chiamare i programmi utente con XEQ nn
// STO nn SUB PER MEMORIZZARE IL CONTENUTO DI X
//NEL REGISTRO INDICATO IN VISORE DA 1 A 19
// MA SE OCCORRE SI PUO' AUMENTARE LE MEMORIE UTENTE
// IN QUEL CASO OCCORRE VARIARE ANCHE LA SUB RCL
// E LA SUB CHE CANCELLA IL CONTENUTO MEMORIE UTENTE
// CIOE LA cancella_mem
void sto_n()
{
int mem = visore;
if (( mem < 1 ) || (mem > 19)) return;
switch (mem)
{
case 1:
mem1 = regx;
break;
case 2:
mem2 = regx;
break;
case 3:
mem3 = regx;
break;
case 4:
mem4 = regx;
break;
case 5:
mem5 = regx;
break;
case 6:
mem6 = regx;
break;
case 7:
mem7 = regx;
break;
case 8:
mem8 = regx;
break;
case 9:
mem9 = regx;
break;
case 10:
mem10 = regx;
break;
case 11:
mem11 = regx;
break;
case 12:
mem12 = regx;
break;
case 13:
mem13 = regx;
break;
case 14:
mem14 = regx;
break;
case 15:
mem15 = regx;
break;
case 16:
mem16 = regx;
break;
case 17:
mem17 = regx;
break;
case 18:
mem18 = regx;
break;
case 19:
mem19 = regx;
break;
}
visore = 0;
} // fine void sto_n
//----------------------------------------------------------------
//RCL richiama in x uno dei registri
void rcl_n()
{
// indirizzo = visore;
int mem = visore;
if (( mem < 1 ) || (mem > 19)) return;
switch (mem)
{
case 1:
{
visore = mem1;
enter();
}
break;
case 2:
{
visore = mem2;
enter();
}
break;
case 3:
{
visore = mem3;
enter();
}
break;
case 4:
{
visore = mem4;
enter();
}
break;
case 5:
{
visore = mem5;
enter();
}
break;
case 6:
{
visore = mem6;
enter();
}
break;
case 7:
{
visore = mem7;
enter();
}
break;
case 8:
{
visore = mem8;
enter();
}
break;
case 9:
{
visore = mem9;
enter();
}
break;
case 10:
{
visore = mem10;
enter();
}
break;
case 11:
{
visore = mem11;
enter();
}
break;
case 12:
{
visore = mem12;
enter();
}
break;
case 13:
{
visore = mem13;
enter();
}
break;
case 14:
{
visore = mem14;
enter();
}
break;
case 15:
{
visore = mem15;
enter();
}
break;
case 16:
{
visore = mem16;
enter();
}
break;
case 17:
{
visore = mem17;
enter();
}
break;
case 18:
{
visore = mem18;
enter();
}
break;
case 19:
{
visore = mem19;
enter();
}
break;
}
visore = 0;
}
//-----------------------------------------------------------
void Xeq_nn()
{
//indirizzo = visore;
int mem = visore;
if (( mem < 1 ) || ( mem > 40)) return;
switch (mem)
{
case 1:
{
//catalog(); // nomi dei programmi di XEQnn
catalog();
}
break;
case 2:
{
carnot(); // soluzione triangolo due lati angolo compreso
}
break;
case 3:
{
parallelo(); // calcola la rt di due resistenze in parallelo
}
break;
case 4:
{
erone(); // 04 calcola triangolo con erone
}
break;
case 5:
{
partitore(); // 05 calcola partitore di tensione
}
break;
case 6:
{
sco_iva(); // 06 scorporo iva
}
break;
case 7:
{
input_out_prog();//07 indicazioni su input output per i programmi
}
break;
case 8: // DA RADIANTI A CENTESIMALI
{
lastx = regx;
regx = regx * 200.0 / PI;
}
break;
case 9:
// da centesimali a radianti
{
lastx = regx;
regx = regx * PI / 200.0;
}
break;
case 10:
//---
break;
case 11:
//----
break;
case 12:
//----
break;
case 13:
//----
break;
case 14:
//-----
break;
case 15:
//-----
break;
case 16:
//----
break;
case 17:
//----
break;
case 18:
// disponibile
break;
case 19:
//----
break;
case 20:
//****
break;
case 21:
break;
case 22:
// disponibile
break;
case 23:
// disponibile
break;
case 24:
// disponibile
break;
case 25:
//------------------
break;
case 26:
// disponibile
break;
case 27:
// disponibile
break;
case 28:
// disponibile
break;
case 29:
// disponibile
break;
case 30:
// disponibile
break;
case 31:
// disponibile
break;
case 32:
// disponibile
break;
case 33:
// disponibile
break;
case 34:
// disponibile
break;
case 35:
// disponibile
break;
case 36:
// disponibile
break;
case 37:
// disponibile
break;
case 38:
// disponibile
break;
case 39:
// disponibile
break;
case 40:
// disponibile
break;
}
visore = 0;
} // fine void XEQ
//***********************************************************
Nessun commento:
Posta un commento
Vi ringrazio per la lettura e vi invito al prossimo post.
Se il post vi è stato utile, vi è piaciuto oppure no, scrivete un commento.
Un saluto a tutti.
Sergio
Copyright - Condizioni d’uso - Disclaimer
http://avventurarduino.blogspot.it/2012/10/inizia-lavventura-arduino-12-settembre.html