Estive a brincar com o arduino, e uma das necessidades que tive foi a de ler grandes números através de serial.
Primeiro, ainda não tive necessidade de usar um programa diferente do monitor de serial com o arduino, por isso fui muito preguiçoso para programar um, e mesmo que tivesse pachorra, o número máximo que conseguiria transmitir de uma só vez seria 255 ... por isso uma solução diferente foi necessária. E eis que cheguei a uma:
long getnumber(char stop_character) {
int cs;
long i = 0;
while(1) {
while(!Serial.available())
delay(100); // Verifica a cada 100 ms -- para não esforçar demais o CPU -- se recebeu dados
cs = Serial.read();
if(stop_character == (char)cs) break; // Recebe os dados e compara-os com o carácter de paragem. Se for igual, pára de receber dados.
if(cs < '0' || cs > '9') continue; // Se não for um dígito ignoramos
i *= 10;
i += (cs-'0'); } // O número resultado avança uma casa decimal para cima, e adiciona o dígito lido (para obter o dígito decimal a partir do caracter, basta subtrair o caracter '0'.
return i; }
Basicamente, esta função lê dígitos do Serial, até chegar a um certo caracter, que recebe como parâmetro (assim pode-se enviar vários números seguidos numa só linha, caso se repita a função, ou um grande número separado por várias linhas -- atenção aos limites de 32 bits do long int. atenção também ao pormenor da função estar escrita para lidar com dígitos, por isso ignora outros caracteres).
O primeiro uso que dei a esta função, foi o de criar um simples despertador, com o auxílio de um buzzer:
int bpin = 11;
void setup() {
pinMode(bpin, OUTPUT);
Serial.begin(9600); }
void loop() {
long int cs, l = 0, f = 0, w = 0;
w = getnumber('S');
Serial.print("Espera: ");
Serial.println(w, DEC);
f = getnumber('S');
Serial.print("Frequencia: ");
Serial.println(f, DEC);
l = getnumber('S');
Serial.print("Duracao: ");
Serial.println(l, DEC);
delay(w*1000);
buzz(bpin, f, l); }
void buzz(int pin, long int f, long int length) {
long int micro_sec = 500000/f,i;
length *= 1000000;
for(i = 0; i < length; i += micro_sec*2) {
digitalWrite(pin, HIGH);
delayMicroseconds(micro_sec);
digitalWrite(pin, LOW);
delayMicroseconds(micro_sec); } }
long getnumber(char stop_character) {
int cs;
long i = 0;
while(1) {
while(!Serial.available())
delay(100); // Verifica a cada 100 ms -- para não esforçar demais o CPU -- se recebeu dados
cs = Serial.read();
if(stop_character == (char)cs) break; // Recebe os dados e compara-os com o carácter de paragem. Se for igual, pára de receber dados.
if(cs < '0' || cs > '9') continue; // Se não for um dígito ignoramos
i *= 10;
i += (cs-'0'); } // O número resultado avança uma casa decimal para cima, e adiciona o dígito lido (para obter o dígito decimal a partir do caracter, basta subtrair o caracter '0'.
return i; }
Basicamente, o programa recebe três números do Serial, e funciona de acordo com os mesmos (dando output a confirmar o recebido). Para saber quando parar de ler cada número, o caracter de paragem usado é o 'S'. O primeiro número corresponde ao número de segundos que o programa irá dormir até soar o despertador, o segundo a frequência do despertador e o terceiro a quantidade de tempo que o despertador irá tocar.
Por exemplo:
3600S2500S5S
Significa que dentro de uma hora, o buzzer irá tocar a uma frequência de 2500hz durante 5 segundos.
Espero que alguém tenha achado isto útil.
Quaisquer correcções são agradecidas.
No futuro, quando tiver acesso a um LCD/teclado compatível com o arduino (tenho algumas ideias para fazer um até xD), talvez arranje uma forma de extender o programa para criar um despertador que não precise do computador para funcionar.