A necessidade é a mãe da invenção, pois, tive a necessidade de resetar um modem ADSL enquanto estava viajando e não perder o acesso remoto aos meu dados. Pra isso tiver que chamar um amigo, pra ir lá na cara do modem e resetá-lo. Muito incomodo pro coitado. Então juntei um antigo modem externo do tempo da internet discada com um Atmega8 e dois relés pra fazer o Modemduino, e controlar os relés remotamente via chamada de voz e o tom das teclas do telefone.
Para confeccionar a placa usei uma técnica bem conhecida, que é explicada neste vídeo do youtube e outros que estão disponíveis lá.
Modemduino Esquemático em PDF: Modemduino Esquemático
A seguir o código fonte do arquivo modemduino.ino:
#include <avr/wdt.h>
#include <avr/interrupt.h>
char inSerial[40];
int i=0;
int ledPin = 8;
int rele1 = 2;
int rele2 = 3;
//boolean x = false;
unsigned long agora;
unsigned long antes;
ISR(TIMER1_COMPA_vect)
{
//x=!x;
setaLed(false);
setaReles(false,false);
TCCR1B = (0 << CS10) | (0 << CS11) | (0 << CS12);
}
void setup() {
wdt_disable();
//pinMode(9, OUTPUT);
//digitalWrite(9,HIGH);
//
DDRB = 0x01;
DDRD |= (1 << 2) | (1 << 3);
//setaLed(true);
TIMSK |= (1 << OCIE1A);
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 30000;
//TCCR1B |= (1 << WGM12)| (0 << CS10) | (0 << CS11) | (1 << CS12);
interrupts();
Serial.begin(57600);
//piscaLed(ledPin);
setaLed(true);
Serial.println(“ATH0”);
delay(100);
readresponse();
setaLed(false);
delay(5000);
initvoicemodem();
setaLed(true);
//piscaLed(100);
wdt_enable(WDTO_2S);
antes = millis();
}
void loop() {
//digitalWrite(ledPin, x);
//setaLed(x);
readresponse();
//setaReles(false,true);
//wdt_reset();
//delay(200);
agora = millis();
if ((agora-antes)>60000) {
setaLed(false);
wdt_enable(WDTO_15MS);
delay(3000);
}
}
void setaLed(boolean x){
if (x) PORTB = 0x01;
else PORTB = 0x00;
}
void setaReles(boolean rl1,boolean rl2){
if (rl1) PORTD |= (1 << 2); //seta rl1
else PORTD &= ~(1 << 2);
if (rl2) PORTD |= (1 << 3); //seta rl2
else PORTD &= ~(1 << 3);
}
void readresponse(){
i=0;
char number;
boolean desliga = false;
wdt_reset();
if (Serial.available() > 0) {
while (Serial.available() > 0) {
inSerial[i]=(Serial.read());
delay(10);
i++;
}
inSerial[i]=’\0′;
//int k = 0;
for (int j=0;j<i;j++) {
if (inSerial[j]==16) { //DLE
number = inSerial[j+1];
if ((number >=’0′) && (number <= ‘9’)) {
setaLed(true);
if(number==’1′) {
setaReles(true,false);
TCCR1B |= (1 << WGM12)| (0 << CS10) | (0 << CS11) | (1 << CS12);
}
if(number==’2′) {
setaReles(false,true);
TCCR1B |= (1 << WGM12)| (0 << CS10) | (0 << CS11) | (1 << CS12);
}
if(number==’0′) {
wdt_enable(WDTO_15MS);
}
break;
}
}
}
inSerial[0]=’\0′;
}
}
void initvoicemodem() {
Serial.println(“AT+FCLASS=8”);
delay(100);
readresponse();
Serial.println(“ATI6”);
delay(100);
readresponse();
Serial.println(“ATS0=4”);
delay(100);
readresponse();
Serial.println(“AT&D0”);
delay(100);
readresponse();
Serial.println(“ATT”);
delay(100);
readresponse();
delay(1000);
}