Делаю "мобильный" телефон на основе стационарного дискового телефона (надо). Почему-то код останавливается на моменте считывания с диска (когда поднимется трубка и геркон размыкается) и в итоге шлет "?". Что не так? Код (C++): #include <SoftwareSerial.h> SoftwareSerial Modem(2, 3); const int _ringPin = 4; const int _headsetPin = 5; const int _speakerPin = 6; const int _resetPin = 11; const int _ledPin = 9; const int _diskActivePin = 12; const int _diskContactPin = 10; bool _diskActive = 0; bool _diskActiveSwitch = 0; bool _diskContact = 0; bool _diskContactSwitch = 0; bool _speakerEnable = 0; bool _WaitEnable = 0; long _WaitTime = 0; int _diskNumber = 10; int _Mode = 0; String _Number = ""; String _temp = ""; void setup() { Serial.begin (9600); Modem.begin(9600); Modem.println("AT"); pinMode (_headsetPin, INPUT); pinMode (_ringPin, INPUT); pinMode (_resetPin, INPUT); pinMode (_ledPin, OUTPUT); pinMode (_diskActivePin, INPUT); pinMode (_diskContactPin, INPUT); Modem.println("AT+DDET=1"); } String readDisk () { Serial.println("readDisk()"); if (digitalRead(_diskActivePin)) { _diskNumber = 0; while (1){ if (!digitalRead(_diskContactPin)) { _diskNumber += + 1; while (!digitalRead(_diskContactPin)) {} } delay(10); if (!digitalRead(_diskActivePin)) { if (_diskNumber == 10) _diskNumber = 0; _WaitTime = millis(); _WaitEnable = 1; Serial.println("PHN" + String(_diskNumber)); break; } } } else _diskNumber = 10; return _diskNumber; } void rington () { if (! millis()% 1000) { if (millis()% 100) tone (_speakerPin, 2800, 100); else tone (_speakerPin, 4186, 100); } } void modemSerial(){ if (Modem.available()) Serial.write(Modem.read()); // ...и выводим их в Serial if (Serial.available()) Modem.write(Serial.read()); // ...и отправляем полученную команду модему } //bool resetButton() {if (digitalRead (_resetPin)) return 1; else return 0;} bool headsetGercon () {if (digitalRead (_headsetPin)) return 1; else return 0; Serial.println("PHHG");} bool ifRing() {if (digitalRead (_ringPin)) return 0; else return 1;} void led (bool enable) {if (enable) digitalWrite (_ledPin, HIGH); else digitalWrite (_ledPin, LOW);} void loop() { again: if (_Mode == 0) { // Режим ожидания if (ifRing()){ _Mode = 1; } if (!headsetGercon()){ _Mode = 2; delay(500); } led(0); } if (_Mode == 1) { //Режим входящего звонка if (!ifRing()) _Mode = 0; if (!headsetGercon()) { delay(100); if (!headsetGercon()) Modem.println ("ATA"); } else { Modem.println ("ATH"); _Mode = 0; } led(0); rington(); } if (_Mode == 2) {//Режим набора номера Serial.println("case: 2"); _Number = _Number + readDisk(); Serial.println(_Number); if (ifRing()) Modem.println ("ATH"); if (headsetGercon()) { Serial.println("Return to Mode 0"); delay (500); _Mode = 0; _Number = ""; _WaitEnable = 0; goto again; } //if (resetButton()) _Number = ""; if (_WaitEnable && millis() - _WaitTime >= 5000) { _WaitEnable = 0; Modem.println("ATD" + _Number + ";"); _Mode = 3; } led(1); } if (_Mode == 3){ //Режим диалога readDisk(); if (_diskNumber != 10) { _temp = ("AT+VTS=" + '"' + _diskNumber + '"'); Modem.println(_temp); } if (headsetGercon()){ _Mode = 0; Modem.println ("ATH"); } led(0); } modemSerial(); }
а почему бы не писать так: Код (C++): mode == wait; mode == dialog; чем запоминать все эти беспонтовые цифры и числа... знак вопроса кто шлет? В коде не вижу. В симуляторе код прогони. и это - где реализация устранения дребезга контактов?
Схема соединений будет? А то так можно на кофейной гуще долго гадать Пока вангую про дикие помехи по сигнальным линиям в процитированный момент - причина появления мусора в приёмном буфере SoftwareSerial.
Вопрос: у вас отдельно впаянный SIM800, или китайская плата? Зачем делитель на RX - модуль, емнип, толерантен к 5В уровням. Стяжка к земле у геркона - не маленький ли номинал? Я бы заменил на 4К7, хотя бы. Вообще - с номиналами всех подтяжек как-то странновато. По остальному - вроде всё ок, значит - надо разбираться, где источник помех. Предлагаю сократить код до минимума, оставив только эхо в Serial от SIM800 - и смотреть, что происходит при срабатывании геркона. Короче - искать источник помех.
Распаянная плата нет. http://codius.ru/articles/251#a38 Ну да. Я просто забыл расписать номиналы На геркон идет 1,5 КОм, на SIM800 - 1 КОм, на контакты диска - 10 КОм. Собрал из чего было)))
Спустя дофига времени я снова вернулся к телефону. Я кажись нашел место, где ARD просто не понимает, что делать и зависает. И это команда Код (C++): Serial.println("PHN" + String(_diskNumber)); А именно String(_diskNumber) Вот код, где поймал баг Код (C++): const int _DiskContactPin = 10; const int _DiskTickPin = 12; int _DiskNumber = 0; void setup() { pinMode (_DiskContactPin, INPUT); pinMode (_DiskTickPin, INPUT); Serial.begin (9600); } String readDisk () { if (digitalRead(_DiskContactPin)) { _DiskNumber = 0; while (1){ if (digitalRead(_DiskTickPin)) { _DiskNumber += + 1; while (!digitalRead(_DiskTickPin)) {} } delay (50); if (!digitalRead(_DiskContactPin)) { if (_DiskNumber == 10) _DiskNumber = 0; Serial.print("PHN"); //Serial.println(String (_DiskNumber)); break; } } } } void loop() { readDisk(); } Есть вариант конвертации int в String без использования String()?