LusoRobótica - Robótica em Português

Sistemas específicos => Arduino / AVR => Tópico iniciado por: Cynary em 30 de Julho de 2010, 11:28

Título: Despertador+Leitura de números por Serial
Enviado por: Cynary em 30 de Julho de 2010, 11:28
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:

Código: [Seleccione]
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:

Código: [Seleccione]
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.