summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Baumann <derflob@derflob.de>2015-12-02 00:38:58 +0100
committerFlorian Baumann <derflob@derflob.de>2015-12-02 00:38:58 +0100
commit86bdb5ad8247db9c44dd9a10a972277dcd780187 (patch)
tree89549daee2bf32cd9ddf4e7532ea5651ebc2f0cc
downloadmFeTAp-86bdb5ad8247db9c44dd9a10a972277dcd780187.tar.gz
mFeTAp-86bdb5ad8247db9c44dd9a10a972277dcd780187.tar.bz2
init
-rw-r--r--mFeTAp.ino384
1 files changed, 384 insertions, 0 deletions
diff --git a/mFeTAp.ino b/mFeTAp.ino
new file mode 100644
index 0000000..6b7e34e
--- /dev/null
+++ b/mFeTAp.ino
@@ -0,0 +1,384 @@
+#include <MsTimer2.h>
+#include <stdio.h>
+#include <SoftwareSerial.h>
+#include "Adafruit_FONA.h"
+
+#define FONA_RX A4
+#define FONA_TX A5
+#define FONA_RST A3
+
+SoftwareSerial fonaSoftwareSerial = SoftwareSerial(FONA_TX, FONA_RX);
+SoftwareSerial *fonaSerial = &fonaSoftwareSerial;
+
+Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
+
+#define PIN_DIAL 2
+#define INT_DIAL digitalPinToInterrupt(PIN_DIAL)
+
+#define PIN_DIGIT 3
+#define INT_DIGIT digitalPinToInterrupt(PIN_DIGIT)
+
+#define PIN_A_BELL 5
+#define PIN_B_BELL 6
+
+#define PIN_INCOMING 7
+
+#define PIN_HANGUP 8
+
+#define PIN_LED 9
+
+#define NUMBER_LEN 30
+
+#define DEFAULT_DIAL_PREFIX "+4989"
+
+volatile int digit = 0;
+volatile int digit_dialed = 0;
+volatile int digit_dialing = 0;
+
+volatile int number_dialed = 0;
+
+char number[NUMBER_LEN] = { '\0' };
+int number_len = 0;
+
+enum adv_states {
+ IDLE,
+ WAIT_FOR_NUMBER,
+ DIALING,
+ SPEAKING,
+
+ BUSY,
+ INCOMING,
+ READING_SMS,
+} adv_state;
+
+void setup() {
+
+ Serial.begin(9600);
+
+ pinMode(PIN_DIAL, INPUT_PULLUP);
+ pinMode(PIN_DIGIT, INPUT_PULLUP);
+
+ pinMode(PIN_A_BELL, OUTPUT);
+ pinMode(PIN_B_BELL, OUTPUT);
+
+ pinMode(PIN_INCOMING, INPUT);
+
+ pinMode(PIN_HANGUP, INPUT_PULLUP);
+
+ pinMode(PIN_LED, OUTPUT);
+
+ digitalWrite(PIN_A_BELL, LOW);
+ digitalWrite(PIN_B_BELL, LOW);
+ digitalWrite(PIN_LED, LOW);
+
+ delay(50);
+
+ attachInterrupt(INT_DIAL, sig_commit_digit, RISING);
+ attachInterrupt(INT_DIGIT, sig_digit, RISING);
+
+ fonaSerial->begin(9600);
+ fona.begin(*fonaSerial);
+
+ fonaSerial->println("AT+STTONE=1,1,1000");
+
+ delay(2000);
+
+ enableGSMBusy(false);
+
+}
+
+void loop() {
+
+ static long inc_time = 0;
+
+ if (fonaSerial->available()) {
+ Serial.write(fonaSerial->read());
+ }
+
+ if (Serial.available()) {
+ fonaSerial->write(Serial.read());
+ }
+
+ if ((millis() % 100) == 0) {
+ Serial.println(adv_state);
+ Serial.println(number);
+ }
+
+ process_input_RI();
+ process_input_hangup();
+ process_input_digit();
+ process_input_number();
+
+ process_output_bell();
+ process_output_speaker();
+
+}
+
+void process_input_RI() {
+
+ switch (adv_state) {
+ case IDLE:
+ if (digitalRead(PIN_INCOMING) == LOW) {
+ // TODO: if PIN_INC is low for 200ms it's an SMS
+ adv_state = INCOMING;
+ }
+ break;
+ }
+}
+
+void process_input_hangup() {
+
+ switch (adv_state) {
+ case IDLE:
+ if (digitalRead(PIN_HANGUP) == LOW) {
+ adv_state = WAIT_FOR_NUMBER;
+ enableGSMBusy(true);
+ delete_number();
+ }
+ break;
+
+ case INCOMING:
+ if (digitalRead(PIN_HANGUP) == LOW) {
+ fona.pickUp();
+ adv_state = SPEAKING;
+ }
+ break;
+
+ case SPEAKING:
+ if (digitalRead(PIN_HANGUP) == HIGH) {
+ fona.hangUp();
+ adv_state = IDLE;
+ enableGSMBusy(false);
+ }
+ break;
+
+ case WAIT_FOR_NUMBER:
+ case DIALING:
+ case BUSY:
+ if (digitalRead(PIN_HANGUP) == HIGH) {
+ delete_number();
+ play_dial_tone(false);
+ enableGSMBusy(false);
+ adv_state = IDLE;
+ }
+ break;
+
+ }
+}
+
+void process_input_digit() {
+
+ switch (adv_state) {
+ case WAIT_FOR_NUMBER:
+ if (digit_dialed && digit > 0 && number_len < NUMBER_LEN) {
+ char d = (digit % 10) + 48;
+ number[number_len] = d;
+ fona.playDTMF(d);
+ number_len++;
+
+ digit = 0;
+ digit_dialed = 0;
+ }
+
+ break;
+ default:
+ digit = 0;
+ digit_dialed = 0;
+
+ break;
+ }
+}
+
+void process_input_number() {
+
+ switch (adv_state) {
+ case WAIT_FOR_NUMBER:
+ if (number_dialed) {
+ adv_state = DIALING;
+ if (!call_current_number(number, &number_len)) {
+ adv_state = IDLE;
+ } else {
+ adv_state = SPEAKING;
+ }
+ number_dialed = 0;
+ }
+
+ break;
+ }
+}
+
+void process_output_bell() {
+
+ static unsigned long inc_time = 0;
+
+ if (adv_state == INCOMING) {
+ if (inc_time == 0) {
+ inc_time = millis();
+ }
+
+ int p = ((millis() - inc_time) / 1000) % 5;
+ if (p > 0){
+ digitalWrite(PIN_LED, LOW);
+
+ digitalWrite(PIN_A_BELL, LOW);
+ digitalWrite(PIN_B_BELL, LOW);
+ } else {
+ digitalWrite(PIN_LED, HIGH);
+
+ p = (millis() / 20) % 2;
+ digitalWrite(PIN_A_BELL, !p);
+ digitalWrite(PIN_B_BELL, !!p);
+ }
+ } else {
+ inc_time = 0;
+ digitalWrite(PIN_LED, LOW);
+
+ digitalWrite(PIN_A_BELL, LOW);
+ digitalWrite(PIN_B_BELL, LOW);
+ }
+}
+
+void process_output_speaker() {
+
+ switch (adv_state) {
+ case WAIT_FOR_NUMBER:
+ if (digit_dialing) {
+ play_dial_tone(false);
+ } else {
+ play_dial_tone(true);
+ }
+ break;
+
+ default:
+ play_dial_tone(false);
+ break;
+ }
+}
+
+void play_DTMF_number(char *numberDTMF) {
+ for (char i = 0 ; numberDTMF[i] != '\0'; i++) {
+ fona.playDTMF(numberDTMF[i]);
+ }
+}
+
+boolean play_dial_tone(boolean enable) {
+ static boolean enabled = false;
+ if (enable == enabled) {
+ return enabled;
+ }
+
+ enabled = enable;
+ if (enable) {
+ return fona.sendCheckReply(F("AT+STTONE=1,1,600000"), F("OK"));
+ } else {
+ return fona.sendCheckReply(F("AT+STTONE=0"), F("OK"));
+ }
+
+}
+
+void delete_number() {
+ Serial.println("Nummer loeschen");
+ memset(number, '\0', NUMBER_LEN * sizeof(char));
+ number_len = 0;
+ number_dialed = 0;
+ digit_dialed = 0;
+}
+
+boolean enableGSMBusy(boolean enable) {
+ if (enable) {
+ return fona.sendCheckReply(F("AT+GSMBUSY=1"), F("OK"));
+ } else {
+ return fona.sendCheckReply(F("AT+GSMBUSY=0"), F("OK"));
+ }
+}
+
+int call_current_number(char *number, int *number_len) {
+ char full[NUMBER_LEN + 6];
+
+ if (number[0] == '0' && number[1] != '0') {
+ sprintf(full, "%s%s", "+49", number+1);
+ } else if (number[0] != '0') {
+ sprintf(full, "%s%s", DEFAULT_DIAL_PREFIX, number);
+ } else {
+ strncpy(full, number, *number_len);
+ }
+
+ Serial.println("Dialing: ");
+ Serial.println(full);
+
+ delete_number();
+
+ //play_DTMF_number(full);
+ return fona.callPhone(full);
+}
+
+void ring_bell(unsigned long inc_time) {
+ int p = ((millis() - inc_time) / 1000) % 5;
+ if (p > 0){
+ digitalWrite(PIN_LED, LOW);
+
+ digitalWrite(PIN_A_BELL, LOW);
+ digitalWrite(PIN_B_BELL, LOW);
+ } else {
+ p = (millis() / 20) % 2;
+ digitalWrite(PIN_A_BELL, !p);
+ digitalWrite(PIN_B_BELL, !!p);
+ digitalWrite(PIN_LED, HIGH);
+ }
+}
+
+void sig_commit_digit() {
+
+ digit_dialed = 1;
+ digit_dialing = 0;
+
+}
+
+void sig_commit_number() {
+
+ MsTimer2::stop();
+
+ number_dialed = 1;
+
+}
+
+void sig_digit() {
+
+ digit_dialing = 1;
+ digit++;
+ digitalWrite(PIN_LED, HIGH);
+ detachInterrupt(INT_DIGIT);
+ MsTimer2::stop();
+ MsTimer2::set(30, sig_att_digit_end);
+ MsTimer2::start();
+
+}
+
+void sig_att_digit_end() {
+
+ MsTimer2::stop();
+ attachInterrupt(INT_DIGIT, sig_digit_end, FALLING);
+
+}
+
+void sig_digit_end() {
+
+ detachInterrupt(INT_DIGIT);
+ digitalWrite(PIN_LED, LOW);
+ MsTimer2::stop();
+ MsTimer2::set(30, sig_att_digit);
+ MsTimer2::start();
+
+}
+
+void sig_att_digit() {
+
+ MsTimer2::stop();
+ attachInterrupt(INT_DIGIT, sig_digit, RISING);
+
+ MsTimer2::set(4000, sig_commit_number);
+ MsTimer2::start();
+
+}
+
+// vim: sw=2