Depois de um bom tempo sem postar no blog vamos continuar de onde paramos...
Vamos à implementação do Agentuino no projeto de monitoramento de temperatura. A idéia básica é fazer com que o Arduino colete a temperatura e disponibilize esta informação via SNMP. O código adaptado ficou assim:
#include<dht11.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Agentuino.h>
byte termometro[8] =//icone para termometro
{
B00100,
B01010,
B01010,
B01110,
B01110,
B11111,
B11111,
B01110
};
byte higrometro[8] = //icone para umidade
{
B00100,
B00100,
B01010,
B01010,
B10001,
B10001,
B10001,
B01110,
};
//codigo rawcode capturado do ar condiconado via IRRecvDump
unsigned int powerOn[92] = {8950,4300,650,500,700,450,650,1600,650,500,600,1650,700,450,650,500,650,500,650,450,600,1700,600,550,550,550,600,1700,600,500,600,550,600,550,600,550,600,500,700,450,600,550,600,550,600,500,600,550,600,550,600,550,550,550,600,550,600,550,600,550,550,550,600,550,600,550,600,500,600,550,650,500,600,550,600,500,600,550,600,550,600,550,550,1700,600,550,600,550,550,1700,700};
// this must be unique
static byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// change network settings to yours
EthernetClient client;
// RFC1213-MIB OIDs
// .iso (.1)
// .iso.org (.1.3)
// .iso.org.dod (.1.3.6)
// .iso.org.dod.internet (.1.3.6.1)
// .iso.org.dod.internet.mgmt (.1.3.6.1.2)
// .iso.org.dod.internet.mgmt.mib-2 (.1.3.6.1.2.1)
// .iso.org.dod.internet.mgmt.mib-2.system (.1.3.6.1.2.1.1)
// .iso.org.dod.internet.mgmt.mib-2.system.sysDescr (.1.3.6.1.2.1.1.1)
static char sysDescr[20] PROGMEM = "1.3.6.1.2.1.1.1.0"; // read-only (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysObjectID (.1.3.6.1.2.1.1.2)
static char sysObjectID[20] PROGMEM = "1.3.6.1.2.1.1.2.0"; // read-only (ObjectIdentifier)
// .iso.org.dod.internet.mgmt.mib-2.system.sysUpTime (.1.3.6.1.2.1.1.3)
static char sysUpTime[20] PROGMEM = "1.3.6.1.2.1.1.3.0"; // read-only (TimeTicks)
// .iso.org.dod.internet.mgmt.mib-2.system.sysContact (.1.3.6.1.2.1.1.4)
static char sysContact[20] PROGMEM = "1.3.6.1.2.1.1.4.0"; // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysName (.1.3.6.1.2.1.1.5)
static char sysName[20] PROGMEM = "1.3.6.1.2.1.1.5.0"; // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysLocation (.1.3.6.1.2.1.1.6)
static char sysLocation[20] PROGMEM = "1.3.6.1.2.1.1.6.0"; // read-write (DisplayString)
// .iso.org.dod.internet.mgmt.mib-2.system.sysServices (.1.3.6.1.2.1.1.7)
static char sysServices[20] PROGMEM = "1.3.6.1.2.1.1.7.0"; // read-only (Integer)
// Arduino defined OIDs
// .iso.org.dod.internet.private (.1.3.6.1.4)
// .iso.org.dod.internet.private.enterprises (.1.3.6.1.4.1)
// .iso.org.dod.internet.private.enterprises.arduino (.1.3.6.1.4.1.36582)
// .iso.org.dod.internet.private.enterprises.arduino.value.valA0-A5 (.1.3.6.1.4.1.36582.3.1-6)
/*
static char valA0[] PROGMEM = "1.3.6.1.4.1.36582.3.1.0"; // read-only (Integer)
static char valA1[] PROGMEM = "1.3.6.1.4.1.36582.3.2.0"; // read-only (Integer)
// .iso.org.dod.internet.private.enterprises.arduino.value.valD0-D13 (.1.3.6.1.4.1.36582.3.7-20)
static char valD0[] PROGMEM = "1.3.6.1.4.1.36582.3.7.0"; // read-only (Integer)
static char valD1[] PROGMEM = "1.3.6.1.4.1.36582.3.8.0"; // read-only (Integer)
*/
static char temp[24] PROGMEM = "1.3.6.1.4.1.36582.3.1.0"; // read-only (Integer)
static char locDescr[20] = "Agentuino";
static char locObjectID[20] = "1.3.6.1.4.1.36582";
static uint32_t locUpTime = 0;
static char locContact[20] = "Eric Gionet";
static char locName[20] = "Agentuino";
static char locLocation[20] = "Nova Scotia, CA";
static int32_t locServices = 7;
static int loctemp = 0;
//uint32_t prevMillis = millis();
uint32_t dispMillis = 0;
char oid[SNMP_MAX_OID_LEN];
SNMP_API_STAT_CODES api_status;
SNMP_ERR_CODES status;
boolean disparou;
boolean disptempo;
// Objeto irsend para emissor infrared
IRsend irsend;
// Objeto rtc (relogio de tempo real)
//RTC_DS1307 rtc;
int sinVal = 0;
int toneVal = 0;
#define lcdAddr 0x20
// Objeto LCD com 2 linhas e 16 caracteres por linha
LiquidCrystal_I2C lcd(lcdAddr, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);
//objeto sensor para DHT11 (sensor de temperatura)
dht11 sensor;
void pduReceived()
{
SNMP_PDU pdu;
Serial.println("UDP Packet Received...");
api_status = Agentuino.requestPdu(&pdu);
if ( (pdu.type == SNMP_PDU_GET || pdu.type == SNMP_PDU_GET_NEXT || pdu.type == SNMP_PDU_SET)
&& pdu.error == SNMP_ERR_NO_ERROR && api_status == SNMP_API_STAT_SUCCESS ) {
pdu.OID.toString(oid);
Serial.print("OID = ");
Serial.println(oid);
if ( pdu.type == SNMP_PDU_SET ) {
status = SNMP_ERR_READ_ONLY;
} else if ( strcmp_P(oid, sysDescr ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locDescr);
} else if ( strcmp_P(oid, sysUpTime ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_TIME_TICKS, locUpTime);
} else if ( strcmp_P(oid, sysName ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locName);
} else if ( strcmp_P(oid, sysContact ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locContact);
} else if ( strcmp_P(oid, sysLocation ) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locLocation);
} else if ( strcmp_P(oid, sysServices) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, locServices);
} else if ( strcmp_P(oid, sysObjectID) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locObjectID);
} else if ( strcmp_P(oid, temp) == 0 ) {
status = pdu.VALUE.encode(SNMP_SYNTAX_INT, loctemp);
} else {
status = SNMP_ERR_NO_SUCH_NAME;
}
pdu.type = SNMP_PDU_RESPONSE;
pdu.error = status;
Agentuino.responsePdu(&pdu);
}
Agentuino.freePdu(&pdu);
}
void adicionazero(int numar) { //this adds a 0 before single digit numbers
if (numar >= 0 && numar < 10) {
lcd.write('0');
}
lcd.print(numar);
}
void lcdnormal(int temp, int umi) {
// DateTime now = rtc.now(); // carrega a data e hora do RTC
lcd.clear(); //limpa o display do LCD.
lcd.home();
lcd.createChar(1,termometro);
lcd.createChar(2,higrometro);
lcd.setCursor(1,0);
lcd.write(1);
lcd.setCursor(3,0);
//lcd.print("Temp: "); //imprime a string no display do LCD.
lcd.print(temp); // imprime a temperatura no LCD
lcd.write((char)223); //Simbolo de graus celsius
lcd.print("C");
lcd.setCursor(10,0);
lcd.write(2);
lcd.setCursor(12,0);
lcd.print(umi); // imprime a umidade no LCD
lcd.print("%");
lcd.setCursor(1, 1);
}
void lcdalto(int temp) {
lcd.clear(); //limpa o display do LCD.
lcd.home();
lcd.createChar(1,termometro);
lcd.setCursor(1,0);
lcd.write(1);
lcd.setCursor(3,0);
//lcd.print("Temp: "); //imprime a string no display do LCD.
lcd.print(temp); // imprime a temperatura no LCD
lcd.write((char)223); //Simbolo de graus celsius
lcd.print("C");
lcd.setCursor(0,1); //posiciona o cursor na coluna 0 linha 1 do LCD.
lcd.print("TEMP. ALTA!"); //Imprime a string no display do LCD.
}
void setup() {
Serial.begin(9600); // Inicia conexao serial para monitoramento
Ethernet.begin(mac);
// Serial.println("Ethernet iniciado");
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
lcd.begin(16,2); // inicializa o lcd
lcd.setBacklight(1);
//Serial.println("LCD iniciado");
pinMode(8,OUTPUT); //pino 8 para saida do alto falante
disparou = false;
disptempo = true;
api_status = Agentuino.begin();
if ( api_status == SNMP_API_STAT_SUCCESS ) {
Agentuino.onPduReceive(pduReceived);
delay(10);
Serial.println("SNMP Agent Initiated...");
return;
} else
{
delay(10);
Serial.print("SNMP Agent failed!");
}
}
void loop() {
int chk = sensor.read(7); //le a temperatura
// Serial.println("Lendo Sensor: ");
/*
//Verifica o status do DHT11
switch(chk) {
case DHTLIB_OK:
Serial.println("OK");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println("Erro no checksum");
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.println("Tempo esgotado");
break;
default:
Serial.println("Erro desconhecido");
}
*/
// Carrega os valores de temperatura e umidade do sensor nas variaveis correspondentes
int t = sensor.temperature;
int u = sensor.humidity;
// Monitora a umidade e temperatura para a conexao serial
/*
Serial.print("Umidade (%): ");
Serial.println(u);
Serial.print("Temperatura (graus Celsius): ");
Serial.println(t);
*/
if (t > 26) { //se temperatura for maior que 26 graus
// Aciona o ar condicionado novamente
//irsend.sendRaw(powerOn,92,38);
if (!disparou) {
// Serial.print("Dispara primeira");
irsend.sendRaw(powerOn,92,38);
dispMillis = millis();
disptempo = false;
//Serial.print("Disparou pela primeira vez");
}
//Aguarda 5 minutos para enviar novamente o codigo IR caso a temperatura nao baixe
if ((millis() - dispMillis > 300000) && (!disptempo)){
irsend.sendRaw(powerOn,92,38);
// Serial.print("Disparou por tempo");
disptempo = true;
}
// Exibe o valor da temperatura lida pelo sensor
lcdalto(t);
//Envia sinal sonoro para o pino 8 - alto falante
for (int x=0; x<180; x++) {
// converte graus para radianos e depois obtem o valor do seno
//Serial.print("Toca o som");
sinVal = (sin(x*(3.1416/180)));
toneVal = 2000+(int(sinVal*1000));
tone(8, toneVal);
delay(2);
}
disparou = true;
delay(2000);
}
else
{
// Temperatura normal
lcdnormal(t,u);
delay(2000);
noTone(8);
disparou = false;
}
Agentuino.listen();
loctemp = t;
}
Cabe aqui algumas considerações sobre a implementação:
1) Complexidade do código e uso de memória SRAM: como vocês podem ver no código que utilizamos muitas variáveis e simplesmente não rodou no Arduino Duemilanove!!! TIve que enxugar ao máximo o código e mesmo assim o Arduino reiniciava. Comprei um Arduino Leonardo com mais SRAM (porém com menos espaço na Flash) e aí rodou bem. Tenho a impressão que o Arduino Leonardo é mais rápido que os outros Arduinos.
2) Uso da serial: se vocês observarem no código eu comentei bastantes linhas de debug de código pela Serial. Isso ajuda a conservar memória porém não permite você analisar mais a fundo se o código está rodando corretamente.
3) Eliminação do uso do shield GSM e do código de envio de e-mail.
Para testarmos se o Agentuino está rodando perfeitamente basta fazer um teste com um cliente snmp via linha de comando:
snmpget -v 1 -r 1 -c public <endereço IP do Arduino> tempousnmpget -v 1 -r 1 -c public <endereço IP do Arduino> 1.3.6.1.4.1.36582.3.1.0Onde:-v 1: versão do SNMP (1)-r 1: número de tentativas (1 tentativa)-c public: nome da community (public)192.168.2.64: ip do arduino que está rodando o agentuino1.3.6.1.4.1.36582.3.1.0 ou temp: OID que armazena a temperaturaO comando deverá retornar a temperatura coletada no momento.No próximo post veremos como implementar o Zabbix para coletarmos e visualizarmos a temperatura através de SNMP.
Dúvidas entrem em contato,
Até a próxima!
Muito bom o seu codigo, poderia nos dizer onde conseguir as bibiotecas para tambem testar ?
ResponderExcluirNas novas versões do Arduino IDE já podem ser feitas o download das bibliotecas na própria IDE vá em:
ExcluirSketck / Include Library / Manage Libraries
Procure por "Agentuino".
Meu caro, como eu obtenho a MIB da umidade ?
ResponderExcluirVocê determina qual o OID vai ser o da umidade. Veja que no código a OID da temperatura é:
Excluirstatic char temp[24] PROGMEM = "1.3.6.1.4.1.36582.3.1.0"; // read-only (Integer)
Você pode acrescentar a OID de umidade assim:
static char umidade[24] PROGMEM = "1.3.6.1.4.1.36582.3.2.0"; // read-only (Integer)
E você tem que criar no restante do código as variáveis que armazenam o valor da umidade.
Alguem já tentou fazer o zabbix se comunicar com o Arduino ?
ResponderExcluirPatrick... tem que conhecer só um pouquinho de redes e SNMP...
ExcluirFernando estou usando seu código, so que esta dando essa mensagem de erro.
ResponderExcluirIn file included from C:\arduino\arduino-1.6.5-r5\hardware\arduino\avr\cores\arduino/Arduino.h:28:0,
from C:\arduino\arduino-1.6.5-r5\libraries\DHT/DHT.h:10,
from temp_snmp.ino:1:
temp_snmp:55: error: variable 'sysDescr' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
temp_snmp:58: error: variable 'sysObjectID' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
temp_snmp:61: error: variable 'sysUpTime' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
temp_snmp:64: error: variable 'sysContact' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
temp_snmp:67: error: variable 'sysName' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
temp_snmp:70: error: variable 'sysLocation' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
temp_snmp:73: error: variable 'sysServices' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
temp_snmp:90: error: variable 'temp' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
temp_snmp:116: error: 'IRsend' does not name a type
temp_snmp:126: error: 'NEGATIVE' was not declared in this scope
temp_snmp:130: error: 'dht11' does not name a type
temp_snmp.ino: In function 'void setup()':
temp_snmp:238: error: no matching function for call to 'LiquidCrystal_I2C::begin(int, int)'
temp_snmp.ino:238:17: note: candidate is:
In file included from temp_snmp.ino:3:0:
C:\arduino\arduino-1.6.5-r5\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:76:7: note: void LiquidCrystal_I2C::begin()
void begin();
^
C:\arduino\arduino-1.6.5-r5\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:76:7: note: candidate expects 0 arguments, 2 provided
temp_snmp.ino: In function 'void loop()':
temp_snmp:268: error: 'sensor' was not declared in this scope
temp_snmp:310: error: 'irsend' was not declared in this scope
temp_snmp:319: error: 'irsend' was not declared in this scope
variable 'sysDescr' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
Levi,
ResponderExcluirVi os erros que estão ocorrendo e o pessoal tem relatado problemas com a versão do seu compilador (1.6.5-r5). Experimente baixar e instalar uma versão anterior e veja se roda.
Boa noite Fernando, obrigado pela atenção, eu baixei a versão 1.6.4 e mesmo assim continua com o mesmo erro.
ExcluirIn file included from C:\ARDUINO-1.6.4\hardware\arduino\avr\cores\arduino/Arduino.h:28:0,
from C:\ARDUINO-1.6.4\libraries\DHT/DHT.h:10,
from DHteste2.ino:1:
DHteste2:55: error: variable 'sysDescr' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
DHteste2:58: error: variable 'sysObjectID' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
DHteste2:61: error: variable 'sysUpTime' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
DHteste2:64: error: variable 'sysContact' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
DHteste2:67: error: variable 'sysName' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
DHteste2:70: error: variable 'sysLocation' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
DHteste2:73: error: variable 'sysServices' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
DHteste2:90: error: variable 'temp' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
DHteste2:116: error: 'IRsend' does not name a type
DHteste2:126: error: 'NEGATIVE' was not declared in this scope
DHteste2:130: error: 'dht11' does not name a type
DHteste2.ino: In function 'void setup()':
DHteste2:238: error: no matching function for call to 'LiquidCrystal_I2C::begin(int, int)'
DHteste2.ino:238:17: note: candidate is:
In file included from DHteste2.ino:3:0:
C:\ARDUINO-1.6.4\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:76:7: note: void LiquidCrystal_I2C::begin()
void begin();
^
C:\ARDUINO-1.6.4\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:76:7: note: candidate expects 0 arguments, 2 provided
DHteste2.ino: In function 'void loop()':
DHteste2:268: error: 'sensor' was not declared in this scope
DHteste2:310: error: 'irsend' was not declared in this scope
DHteste2:319: error: 'irsend' was not declared in this scope
variable 'sysDescr' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
Fernando nitatori, ainda eu não consegui fazer funcionar o código, poderia me ajudar?
ResponderExcluirResolvi o problema pessoal:
ResponderExcluircoloque const na frente das static char
Que bom! Está funcionando certinho? Conseguiu ler a temperatura via SNMP ?
ExcluirCom o const consegui, mudei a versão da IDE e o modelo do arduino e não funcionou. Não entendo...
ExcluirPessoal, conseguiram fazer funcionar? O código acima funcionou para mim e para algumas versões do Arduino IDE ou até mesmo para outros Arduinos pode ter diferenças e dar problemas.
ResponderExcluirO código funcionou bem, consigo coletar via linha de comando a OID referente ao sensor que estou tentando utilizar. Maravilha! Porém quando eu coloco um IP para de acesso externo não consigo obter a OID. Alguém teve esse problema?
ResponderExcluirnao consegui compilar o código, creio que estou me perdendo nas bibliotecas, onde posso acha-las?
ResponderExcluir/var/folders/bp/93hys7xj0zxd5t6hpg0_qpyw0000gn/T/arduino_modified_sketch_642501/AnalogReadSerial.ino:1:19: fatal error: dht11.h: No such file or directory
ResponderExcluir#include
^
compilation terminated.
exit status 1
Erro compilando para a placa Arduino/Genuino Mega or Mega 2560
esse é o erro que esta apresentando. podem me ajudar?
Você baixou as bibliotecas necessárias? Em meus posts anteriores tem os links para baixar as bibliotecas.
ExcluirSe eu quiser colocar mais de um sensor de temperatura, como faço para colocar mais OIDs?
ResponderExcluirFernando, conseguiu fazer funcionar com apenas 1 sensor?
ResponderExcluirSim. Consegui sem problemas e dá para usar mais sensores.
ExcluirMuito bom o seu post, era justamente o que eu estava procurando. Só não entendi em que parte do seu código inseriu o valor da temperatura (t) dentro da OID 1.3.6.1.4.1.36582.3.1.0. Poderia esclarecer ?
ResponderExcluirAlguém conseguiu rodar? Eu consigo compilar o exemplo Agente sem erros porém quando uso o snmpget para verificar os valores da timeout.
ResponderExcluirEstou usando o Arduino Uno e a versão da IDE é 1.8.19.0.
Bom dia gostaria de um código igual a esse com mais alguns sensores de tensão e corrente alguém teria algum para disponibilizar ou não tenho mto mas pago pelo código.
ResponderExcluirEmail eletroinfotecnologia@gmail.com
ExcluirTentei aqui e não funcionou tambem, tive que alterar tambem o display para oled mas, as bibliotecas Agentuino e dht11 não acha, mesmo instaladas, e atualizadas.
ResponderExcluir