Pull to refresh
1794.43
Timeweb Cloud
То самое облако

Телефон на 600 квартир

Level of difficultyMedium
Reading time7 min
Views24K
Приветствую всех!
Когда-то давно попался мне на просторах вот такой мем:


Посмотрел я тогда на всё это и забыл. А недавно, встретив его ещё раз, подумал: что, если попробовать сделать такой девайс в реальности? Как насчёт собрать такой телефон, по которому в самом деле можно будет позвонить? Именно этим-то мы сейчас и займёмся.

Суть такова


Вообще, проектов самодельных «звонилок» на микроконтроллере довольно много, от совсем простеньких до вот таких вот очень крутых. Я и сам уже давно хотел приобщиться и собрать что-то интересное, и вот как раз недавно выдался подходящий случай: шутки ради соберём аппарат в виде блока вызова домофона. Само собой, пользоваться этой штукой постоянно я не собираюсь, но получиться должно очень эффектно.

Обзор оборудования


Перво-наперво для создания данного прибора понадобится домофон. В оригинальном меме был Cyfral CCD-20, так что достанем именно его.



А вот и он. Для переделки специально раздобыл нерабочий аппарат, дабы было не жалко его препарировать. К сожалению, экземпляра с RFID-считывателем, как в оригинале, не нашёл, так что обойдёмся контактным.



Обратная сторона. Вообще, тут должна была быть крышка, но у меня её нет. К слову говоря, Cyfral CCD-20 на самом деле координатный домофон со встроенным коммутатором на двадцать абонентов, никакими шестьюстами тут даже не пахнет. Также видны нераспаянные места под два транзистора, позволяющие расширить число квартир до сорока и задействованные в модели CCD-40.



А вот другой экземпляр. Так выглядит домофон в сборе с крышкой.

Первый запуск


И для начала посмотрим на то, как проявляется неисправность.



При подаче питания домофон ожил. Можно даже попробовать куда-нибудь позвонить…



А вот считыватель оказался неисправен: домофон не читает ключи. Судя по всему, пострадал он из-за грозы или вандалов с электрошокером.



К сожалению, проблема здесь кроется в выгоревшей ножке микроконтроллера, а не в обвязке считывателя, что было проверено установкой чипа в другой, заведомо рабочий блок вызова. Прошитый микроконтроллер на замену стоит немногим дешевле живого домофона, так что в нашу эпоху массовой замены таких домофонов на IP мало кто возьмётся за такой ремонт. В некоторых местах изворачиваются путём установки внешнего контроллера ключей, но там, где обслуживался этот домофон, его просто заменили целиком.

Электроника


Как и любой другой простенький проект, собирать всё будем из электронных модулей.



В основе будет неоригинальная плата Raspberry Pico на чипе RP2040 — просто потому что она дешёвая, питается сразу от аккумулятора и работает с трёхвольтовыми логическими уровнями, что нам и нужно. Да и потенциал для дальнейшего развития проекта тоже будет отличный.



Питать всё это будем от двух литий-ионных аккумуляторов от израсходованных одноразовых «дудок». Благодаря моему товарищу, который курит эту гадость, дефицита таких элементов питания я не испытываю.



Усилитель. В качестве него взял вот такой модуль на чипе PAM8403, некогда купленный для информатора УСАВП, но впоследствии так и не пригодившийся. Для динамика домофона его с лихвой хватит.



Семисегментный индикатор KEM-3631AR. Похожий стоит на оригинальной плате домофона.



GSM-модуль SIM800L, точнее, китайская плата с этим модулем.



Сам модуль явно видавший виды и откуда-то выпаянный, но на работу это повлиять не должно. Вообще, использовать внешний МК для управления этим модулем — лютый оверинжиниринг, так как у него самого есть GPIO и все необходимые интерфейсы (по сути внутри него baseband и RF-frontend от простенького телефона). Однако вся документация и инструментарий для сборки своей прошивки доступны только под NDA, а слитых файлов я нигде не нашёл, так что этим всем займёмся как-нибудь в другой раз, когда всё это удастся найти.

Разбираем домофон


Теперь осталось убрать плату, оставив только нужное нам.



Откручиваем винты и снимаем её.



Обратная сторона.



Плату управления, разумеется, не выкидываем — возможно, пригодится для оживления другого домофона с целым МК. В этих панелях часто вылетают транзисторы встроенного коммутатора, отчего экземпляр перестаёт звонить.

Схема


Перед сборкой разберёмся с подключением.



А вот и схема девайса. Красивой не будет, есть только традиционная.
В качестве источника питания — ранее упомянутый литиевый аккумулятор. Подключён он через диод Шоттки для того, чтобы плата при работе от USB и оставленном в рабочем положении выключателе не пыталась его заряжать. Вообще, питанию надо уделить особое внимание, так как модуль при поиске сети может кратковременно потреблять ток до пары ампер. Из-за этого платы защиты аккумулятора на меньший ток не подойдут, так как будут принимать такие резкие броски как короткое замыкание.
Подсветку клавиатуры подключил к VBAT — этакий индикатор того, что устройство работает от батарей.



Остановимся поподробнее на клавиатуре блока вызова. Она не полностью матричная: одна из кнопок выведена отдельно. Сделано это из-за того, что в «Цифрале» кнопка сброса не даёт некую команду, а просто перезагружает микроконтроллер. Поэтому её контакты необходимо подключить к соответствующей строке и соответствующему столбцу.

Собираем домофон




Как это часто бывает, интересная идея пришла слишком поздно и на разводку платы энтузиазма не осталось. Поэтому собираем на зелёной монтажной плате.



Отрезаем под размер оригинальной платы и сверлим монтажные дырки отверстия.



Устанавливаем переключатель питания, светодиоды подсветки и индикатор.



На смену поднадоевшей жёлтой подсветке поставим синюю.



Убедившись, что плата не перестала вписываться в габариты, ставим всё остальное.



Когда большая часть проводов припаяна, можно проверить, как оно работает.



Наконец, собираем всё окончательно.

Прошивка контроллера


Для первого раза решил попробовать реализовать самую главную функцию — звонки.

Вот что получилось
#define SEG_A 16
#define SEG_B 17
#define SEG_C 18
#define SEG_D 19
#define SEG_E 20
#define SEG_F 21
#define SEG_G 22

#define DIGIT_1 26
#define DIGIT_2 27
#define DIGIT_3 28

#define BEEP 9

#define sim800 Serial1

const byte ROWS = 4;
const byte COLS = 3;
byte rowPins[ROWS] = {5, 6, 7, 8};
byte colPins[COLS] = {2, 3, 4};

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'C', '0', 'K'}
};

const byte digitSegments[10] = {
  B00111111, // 0
  B00000110, // 1
  B01011011, // 2
  B01001111, // 3
  B01100110, // 4
  B01101101, // 5
  B01111101, // 6
  B00000111, // 7
  B01111111, // 8
  B01101111  // 9
};


char digitBuffer[3] = {' ', ' ', ' '};
byte bufferIndex = 0;

String numberBuffer = "";

char getKey() {
  char key = 0;

  for (byte c = 0; c < COLS; c++) {
    digitalWrite(colPins[c], LOW);

    for (byte r = 0; r < ROWS; r++) {
      if (digitalRead(rowPins[r]) == LOW) {
        delay(50);
        while (digitalRead(rowPins[r]) == LOW);
        key = keys[r][c];
      }
    }

    digitalWrite(colPins[c], HIGH);
  }

  return key;
}


void displayBuffer() {
  int d1 = (digitBuffer[0] == ' ') ? 10 : digitBuffer[0] - '0';
  int d2 = (digitBuffer[1] == ' ') ? 10 : digitBuffer[1] - '0';
  int d3 = (digitBuffer[2] == ' ') ? 10 : digitBuffer[2] - '0';

  showDigit(d1, DIGIT_1);
  delay(1);
  showDigit(d2, DIGIT_2);
  delay(1);
  showDigit(d3, DIGIT_3);
  delay(1);
}

void showDigit(int digit, int digitPin) {
  digitalWrite(DIGIT_1, HIGH);
  digitalWrite(DIGIT_2, HIGH);
  digitalWrite(DIGIT_3, HIGH);

  // Если digit = 10 (пробел), выключаем все сегменты
  if (digit == 10) {
    for (int i = SEG_A; i <= SEG_G; i++) {
      digitalWrite(i, LOW);
    }
  } else {
    byte segments = digitSegments[digit];
    digitalWrite(SEG_A, segments & 0x01);
    digitalWrite(SEG_B, segments & 0x02);
    digitalWrite(SEG_C, segments & 0x04);
    digitalWrite(SEG_D, segments & 0x08);
    digitalWrite(SEG_E, segments & 0x10);
    digitalWrite(SEG_F, segments & 0x20);
    digitalWrite(SEG_G, segments & 0x40);
  }

  digitalWrite(digitPin, LOW);
}

void makeCall(String phoneNumber) {
  sim800.println("ATD" + phoneNumber + ';');
  delay(100);
}

void answerCall() {
  sim800.println("ATA");
  delay(100);
}

void rejectCall() {
  sim800.println("ATH0");
  delay(100);
}

void setup() {
  for (int i = SEG_A; i <= SEG_G; i++) {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }

  pinMode(DIGIT_1, OUTPUT);
  pinMode(DIGIT_2, OUTPUT);
  pinMode(DIGIT_3, OUTPUT);

  digitalWrite(DIGIT_1, HIGH);
  digitalWrite(DIGIT_2, HIGH);
  digitalWrite(DIGIT_3, HIGH);

  for (byte c = 0; c < COLS; c++) {
    pinMode(colPins[c], OUTPUT);
    digitalWrite(colPins[c], HIGH);
  }

  for (byte r = 0; r < ROWS; r++) {
    pinMode(rowPins[r], INPUT_PULLUP);
  }
  sim800.begin(115200);
}

void loop() {
  char key = getKey();

  if (key) {
    tone(BEEP, 800, 80);
    if (key >= '0' && key <= '9') {
      digitBuffer[0] = digitBuffer[1];
      digitBuffer[1] = digitBuffer[2];
      digitBuffer[2] = key;
      numberBuffer += key;
    }
    if (key == 'K') {
      if (numberBuffer.length() == 0) answerCall();
      else {
        makeCall(numberBuffer);
        digitBuffer[0] = ' ';
        digitBuffer[1] = ' ';
        digitBuffer[2] = ' ';
        numberBuffer = "";
      }
    }
    else if (key == 'C')
    {
      digitBuffer[0] = ' ';
      digitBuffer[1] = ' ';
      digitBuffer[2] = ' ';
      numberBuffer = "";
      rejectCall();
    }
  }

  displayBuffer();
}


Звук нажатия кнопок постарался подобрать похожий на тот, что стоит в настоящем домофоне.

Как это вообще работает?


Загружаем прошивку и идём пробовать.



Выглядит, конечно, презабавно, особенно для неподготовленных. Даже скажу, что получилось ещё эффектнее, чем думал изначально.



Товарищи восприняли это с энтузиазмом и даже предложили продолжить идею и собрать планшет из «Элтиса».

Но не обошлось и без нюансов. Самый главный из них в том, что используемый тут усилитель не очень подходит для такого применения.

Обычно все просто подключают к модулю динамик и микрофон и радуются жизни. И действительно, восьмиомный динамик или разъём для наушников для многих проектов отлично подходят. А вот по запросу «sim800 amplifier connection» чего-то дельного удивительно мало, так что восполню это упущение. Дело в том, что модуль не только очень много потребляет, но и безбожно фонит (на видео посторонний шум примерно вдвое громче реального), поэтому усилитель для него подойдёт далеко не всякий.



Решить эту проблему конденсаторами по питанию не вышло, так что наилучшим решением будет либо поставить фильтр или мелкий сигнальный трансформатор (как в ЦПИ, который вообще никак не фонит), либо использовать другой усилитель (аналоговая земля которого не связана с землёй питания, по которой, вероятно, и идут наводки).
Впрочем, несмотря на все косяки девайс свою задачу отлично выполнил.

Что же в итоге?


Вот такой забавный девайс получился. Впрочем, на этом его жизнь не заканчивается: добавить там есть очень много чего. В частности, чуть позже попробую переписать работу с клавиатурой и дисплеем с использованием PIO, реализовать режим программирования как в настоящем домофоне и как-то обыграть упомянутые в том меме 600 квартир (например, сделать 600 ячеек для быстрого набора). И, конечно же, надо будет исправить тот косяк с усилителем.

Такие дела.



Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале



Перед оплатой в разделе «Бонусы и промокоды» в панели управления активируйте промокод и получите кэшбэк на баланс.

Другие мои посты про ключи, домофоны, считыватели и прочие подобные устройства:

Tags:
Hubs:
+134
Comments53

Articles

Information

Website
timeweb.cloud
Registered
Founded
Employees
201–500 employees
Location
Россия
Representative
Timeweb Cloud