Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

HashMaps – Arrays Associativos com Arduino

Tags: string

Simplifique seus programas com o uso de HashMaps e outras estruturas de dados em Arduino

Introdução

Quando se trata de programação de computadores (ou microcontroladores), a escolha da estrutura de dados a ser utilizada  pode tornar um problema complicado em um de solução relativamente simples ou vice-versa!

A plataforma Arduino disponibiliza em sua API várias opções de tipos de dados compostos que podem ser utilizados pelo programador como por exemplo: Arrays, Strings, Structs, etc. No entanto, algumas vezes essas estruturas não são suficientes para a resolução de determinados tipos de problemas e, então, precisamos buscar soluções em bibliotecas externas.

Neste artigo, vamos demonstrar o uso de uma estrutura de dados muito conhecida entre os programadores PHP e Python: Os Arrays Associativos, também conhecidos  como HashMaps ou Dicionários. Veremos como eles podem facilitar sua vida.

Antes disso, vamos recordar algumas tipos de dados estruturados básicos da plataforma Arduino…

Arrays

Arrays ou vetores são estruturas de dados que representam um conjunto de variáveis com o mesmo nome identificadas individualmente através de um índice.

Na linguagem de programação do Arduino, os arrays possuem as seguintes características:

  • Todos elementos devem possuir o mesmo tipo;
  • O número de elementos é imutável;
  • O índice é um número sequencial que inicia em 0 (zero) e vai até (N-1), onde N é o número de elementos do array

Portanto, para declararmos um array, devemos informar 3 coisas:

  1. O nome do vetor
  2. O número máximo de elementos que ele vai conter
  3. O tipo de dados dos elementos.

Por exemplo, a declaração abaixo vai criar um array com 3 elementos inteiros:

int myPin[] = {2, 4, 8};
Onde myPin[0] = 2, myPin[1] = 4 e myPin[2] = 8.

Strings

Uma String na linguagem do Arduino é uma classe que representa um conjunto de caracteres e disponibiliza vários métodos para manipulação de textos.
Cada caractere da String pode ser acessada por um índice numérico que inicia em 0 (zero) e vai até (N-1), onde N é o tamanho da String.

Exempo: O comando abaixo cria uma String de 7 caracteres com o valor “Arduino”:

String board = “Arduino”;
Onde:
board.length() = 7 → Tamanho da String
board.indexOf(0) = “A” → Primeira letra da String
board.indexOf(“i”) = 4 → Posição da letra “i” na string
board.toUpperCase() = “ARDUINO”→ Transforma as letras para maiúsculo

Arrays Associativos

Trata-se de um tipo de array  ondes os elementos são formados por um par chave e valor (key-value pairs),  no qual cada chave possui um valor associado. Essa chave pode assumir qualquer tipo de valor, inclusive Strings. As chaves são definidas pelo usuário e são armazenadas na estrutura. O relacionamento existente entre as chaves e seus respectivos valores é chamado de mapeamento, pois, para buscar um valor utiliza-se a chave como índice de busca. Pode-se buscar o valor de um elemento pela chave e também verificar se existe algum elemento relacionado àquela chave.

A principal vantagem existente na utilização de vetores associativos está na facilidade de realização de buscas por valores, que é mais intuitiva.

Existem algumas implementações de HashMaps que podem ser usadas com o Arduino. Destacamos os seguintes frameworks:

  1. Wiring – An open-source programming framework for microcontrollers
  2. STL – The Standard Template Library

Neste artigo, vamos adotar nos exemplos a biblioteca da plataforma Wiring, que inclui um implementação de HashMaps desenvolvida por Alexander Brevig. Você vai precisar “importar” os arquivos hashmap.hCountable.h para a pasta libraries  do Arduino.

Veja um exemplo onde vamos criar um array associativo com 3 elementos inteiros com índices do tipo String:

 CreateHashMap(myPin, char*, int, 3);
 myPin[“Sensor”] = 2;
 myPin[“Led”] = 4;
 MyPin[“Buzzer”] = 8;

Observe, no exemplo que associamos a chave “Sensor” ao valor 2. A vantagem dessa implementação é que podemos identificar o primeiro elemento por sua chave “Sensor” ou pelo seu índice que é 0 (zero).

Para entendermos melhor esses conceitos, vamos elaborar um projeto simples como exemplo e resolvê-lo de 3 formas distintas:

  • Sem Estruturas de Dados
  • Utilizando Strings
  • Utilizando Arrays Associativos

Estudo de caso

O nosso projeto consiste de 3 leds coloridos ligados aos pinos 5, 7, 9 e 11 do Arduino, conforme figura abaixo:

Arduino Project – 4 leds

A aplicação em Arduino vai ler valores String pela porta serial em um loop infinito. Para cada valor lido, a seguinte ação será executada:

  1. Se leitura = “red” -→ Acender led vermelho
  2. Se leitura = “yellow” → Acender led amarelo
  3. Se leitura = “green” → Acender led verde
  4. Se leitura = “blue” → Acender led azul

Sketchs

Solução 1: Sem Estruturas de Dados

/* Arduino & 4 leds
 * Solution 1: Without Data Structures 
 * 2016, by José Cintra
 * http://www.josecintra.com/blog
 */
String reading = "";
int redPin = 5;
int greenPin = 7;
int bluePin = 9;
int yellowPin = 11;

void setup() {
  Serial.begin(9600);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT); 
  pinMode(bluePin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
}

void loop() {
  reading = readSerial(); //Reads value from serial
  ledsOff(); // Turn off all leds
  if (reading == "red") {
    digitalWrite(redPin,HIGH);
  }
  else if (reading == "green") {
    digitalWrite(greenPin,HIGH);
  }
  else if (reading == "blue"){
    digitalWrite(bluePin,HIGH);
  }
  else if (reading == "yellow"){
    digitalWrite(yellowPin,HIGH);
  }
}

//Read String from Serial
String readSerial() {
  String retVal = "";
  char c;
  while(!Serial.available()){ //Wait for serial input
    delay(10);
  }
  while(Serial.available() > 0) { //Read the serial input
    c = Serial.read();
    if (c != '\n'){
      retVal.concat(c);
    }
    delay(10);
  }
  retVal.toLowerCase(); //Convert to lower case
  return retVal; 
}  

//Turn off all leds
void ledsOff(){
  digitalWrite(redPin,LOW); 
  digitalWrite(greenPin,LOW); 
  digitalWrite(bluePin,LOW);
  digitalWrite(yellowPin,LOW);
}

Solução 2: Usando Arrays e Strings

/* Arduino & 4 leds
 * Solution 2: With Arrays & Strings 
 * 2016, by José Cintra
 * http://www.josecintra.com/blog
 */
String reading = "";
int pins[] = {5,7,9,11};
String commands = "red       green     blue      yellow    ";

void setup() {
  Serial.begin(9600);
  for(int i = 0; i < 4; i++){
    pinMode(pins[i], OUTPUT);
  }
}

void loop() {
  reading = readSerial(); //Read value from serial
  ledsOff(); // Turn off all leds
  int i = commands.indexOf(reading);
  if (i >= 0) {  
    digitalWrite(pins[(i / 10)],HIGH);
  }
}

//Read String from Serial
String readSerial() {
  String retVal = "";
  char c;
  while(!Serial.available()){ //Wait for serial input
    delay(10);
  }
  while(Serial.available() > 0) { //Read the serial input
    c = Serial.read();
    if (c != '\n'){
      retVal.concat(c);
    }
    delay(10);
  }
  retVal.toLowerCase(); //Convert to lower case
  return (retVal); 
}  

//Turn off all leds
void ledsOff(){
  for(int i = 0; i < 4; i++){
    digitalWrite(pins[i],LOW);
  }
}

Solução 3: Usando HashMaps

/* Arduino & 4 leds
 * Solution 3: With HashMaps
 * 2016, by José Cintra
 * http://www.josecintra.com/blog
 */
#include <HashMap.h>
String reading = "";
CreateHashMap(ledPins, String, int, 4);

void setup() {
  Serial.begin(9600);  
  ledPins["red"] = 5;
  ledPins["green"] = 7;
  ledPins["blue"] = 9;
  ledPins["yellow"] = 11;
  for (int i = 0; i < ledPins.size(); i++){ 
    pinMode(ledPins.valueAt(i), OUTPUT);
  }  
}

void loop() {
  reading = readSerial();
  ledsOff();
  if(ledPins.contains(reading)){
    digitalWrite(ledPins[reading],HIGH);
  }
}

//Read String from Serial
String readSerial() {
  String retVal = "";
  char c;
  while(!Serial.available()){ //Wait for serial input
    delay(10);
  }
  while(Serial.available() > 0) { //Read the serial input
    c = Serial.read();
    if (c != '\n'){
      retVal.concat(c);
    }
    delay(10);
  }
  retVal.toLowerCase(); //Convert to lower case
  return retVal; 
}  

//Turn off all leds
void ledsOff(){
  for (int i = 0; i < ledPins.size(); i++){ 
    pinMode(ledPins.valueAt(i), LOW);
  }  
}

Pontos de Interesse

  1. A função readSerial, presente nas 3 soluções tem a função de aguardar e ler um valor String pela porta serial;
  2. A função ledsOFF tem a função de apagar todos os leds antes de acender o led solicitado pelo comando da serial;
  3. Repare, comparando a função loop das 3 soluções, que a alternativa usando arrays associativos é bem mais legível, compacta e manutenível;
  4. A alternativa 2 com arrays e strings tem a vantagem de não precisar usar nenhuma biblioteca externa.

Recursos

  • https://en.wikipedia.org/wiki/Associative_array
  • https://www.arduino.cc/en/Reference/StringObject
  • https://www.arduino.cc/en/Reference/Array
  • Versão em inglês do artigo

Conclusão

Neste artigo procuramos mostrar que a escolha de estruturas de dados apropriadas pode resultar em programas mais intuitivos e compactos, facilitando o trabalho do programador.

Saudações Klingonianas…

0
1
0
0
0
0
0

O post HashMaps – Arrays Associativos com Arduino apareceu primeiro em BlogDoJoséCintra.



This post first appeared on BlogDoJoséCintra, please read the originial post: here

Share the post

HashMaps – Arrays Associativos com Arduino

×

Subscribe to Blogdojosécintra

Get updates delivered right to your inbox!

Thank you for your subscription

×