Упрваление микроконтроллером со смартфона

step962
Offline
Зарегистрирован: 23.05.2011

Наигравшись за осень и зиму с разными TFT-дисплеями и разочаровавшись в их возможностях, решил подойти к дачному сезону с более удобным вариантом. Выбор пал на смартфон – все равно болтается в карманах и у меня, и у жены. Имеет при этом достаточно большой по размеру и оставляющий далеко позади все дисплейчики в плане разрешения и яркости красок. Индуктивный сенсорный экран, опять же, позволяет управлять пальцем. Ну и общение с любым устройством из любого места дачи тоже имеет свои достоинства.

Среди возможных для реализации каналов связи – USB, Bluetooth и WIFI – выбор пал на последний. С USB все понятно – со шнурком никакой мобильности не получается. Подключать Bluetooth к младшим Arduino не имеет смысла, так как очень высока вероятность с первых же шагов натолкнуться на проблему недостатка оперативной памяти, для подготовки команд управления дисплеем и обработки поступающей от него информации. Ну, а в последнее время где WIFI, там сразу приходит на ум и ESP8266: тут тебе и WIFI, и оперативка целых 80 кб, и флеш-памяти до … горизонта, и тактовая частота солидная. Да и цена не намного выше, чем у Bluetooth-модуля. В общем, отличный вариант для работы не только в качестве центрального командного пункта, управляющего армией микроконтроллеров, но даже и для подключения к каждому имеющемуся модулю (в качестве WIFI-моста между смартфоном и модулем)  или полной их замены на ESP8266.

В настоящее время реализован первый вариант – смартфон в качестве тонкого клиента и ESP8266 в качестве командного узла. Два вторых варианта предполагают наличие нескольких модулей ESP8266, работающих в режиме точек доступа, а значит и геморрой с постоянным переключением между точками доступа. Облегчить этот процесс, в принципе, возможно, но … потом, потом.

Использовать смартфон в качестве точки доступа не хочется по нескольким причинам. Во-первых, в таком варианте придется постоянно включать-выключать режим модема, что подходит не для всех членов коллектива. Во-вторых,  коммуникация будет завязана на одно-единственное Android-устройство. В-третьих, число одновременных соединений у некоторых устройств ограничено и можно попасть в ситуацию, когда часть модулей просто не сумеет подключиться.

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

Сейчас реализовано несколько простейших команд:

FG     Задание цвета точек/прямых
FD     Задание цвета переднего и заднего фона дисплея
FZ     Задание цвета для вывода текста (шрифт и фон)
GD     Рисование прямой по двум точкам
GR     Рисование прямоугольника по двум точкам
GW     Рисование прямой из текущей точки в точку с указанными координатами
ZL     Вывод текста с выравниванием влево
ZC     Вывод текста с выравниванием по центру
ZR     Вывод текста с выравниванием вправо
DL     Заливка графической области дисплея цветом заднего фона
DS     Заливка графической области дисплея цветом переднего фона
RF     Заливка прямоугольной области
RL     Стирание прямоугольной области (заливка цветом заднего фона)
RS     Заливка прямоугольной области цветом переднего фона

Но уже этого достаточно, чтобы создать достаточно информативную картинку и построить, например, меню.

Ниже приведу простенький скетч, который реагирует на две команды - "drw" и "redrw", отправляемые при нажатии на кнопки "Send Draw" и "Send Redraw" соответственно:


#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <stdio.h>
#include <string.h>


// Имя точки доступа и пароль:
const char *ssid = "espTestAP";
const char *password = "smartDisplay";
String sResponse;

ESP8266WebServer server(80);


void drawRectangles() {
  char s[30];
  int i;
  for(i=0;i<20;i++) {
    sprintf(s,"#GR%d,%d,-%d,-%d;",i*10,i*12,i*10,i*12);
    sResponse += s;
  }
}

void drwTest() {
  char s[30];
  int i,j;
    sResponse += "#RF0,0,-1,-1,1;"; // халивка графической части экрана черным цветом
    for(i=1;i<=16;i++) {
        sprintf(s,"#FG%d,1;",i);
        sResponse += s;
        for(j=0;j<4;j++) {
            sprintf(s,"#GD%d,40,%d,-40;",i*16+j,i*16+j);
            sResponse += s;
        }
        j = i-1;
        sprintf(s,"#GR-%d,%d,-%d,%d;",(j/4)*40+20,(j%4)*40+20,(j/4)*40+50,(j%4)*40+50);
        sResponse += s;
        sprintf(s,"#RF-%d,%d,-%d,%d,%d;",(j/4)*40+220,(j%4)*40+20,(j/4)*40+250,(j%4)*40+50,i);
        sResponse += s;
    }
}

void redrwTest() {
  int i;
  char s[30]; 
  sResponse += "#FG4,1;";
  sResponse += "#GD-10,-10,-500,-500;#GD-10,-500,-500,-10;";
  for(i=5;i<500;i+=10) {
    sprintf(s,"#GD-%d,-%d,-%d,-%d;\0",10,500-i,i,10);
    sResponse += s;
  }
}


void handleRoot() {
  sResponse = "<h1>You are connected</h1>";
  Serial.print(" URI: "); Serial.println(server.uri());
  Serial.print("Args: "); Serial.println(server.args());
  for(int i=0;i<server.args();i++) {
    Serial.print(i); Serial.print(": ");
    Serial.print(server.argName(i)); Serial.print(": ");
    Serial.println(server.arg(i)); 
  }
  if(server.arg(0).equals("drw")) drwTest();
  if(server.arg(0).equals("redrw")) redrwTest();
  Serial.print("response len: ");
  Serial.print(sizeof(sResponse));
  Serial.print(" - ");
  Serial.println(sResponse.length());
  server.send(200, "text/html", sResponse);
}

void startServer() {
  server.on("/", handleRoot);
  server.begin();
  Serial.println("== HTTP server started");
}

void startAsAccessPoint() {
  delay(1000);
  Serial.println("-- Configuring access point...");
  // вызов функции WiFi.softAP с задержкой (delay(1000)) приводит к неправильной иниацилизации режима
  // (возвращается IP-адрес - успевает включиться режим по умолчанию "Станция"???)
  // Чтобы этого не происходило, рекомендуется вызывать функции WiFi.disconnect/WiFi.softAPdisconnect
  // непосредственно перед WiFi.softAP
  WiFi.disconnect();
  WiFi.softAPdisconnect();
  
  WiFi.mode(WIFI_AP);
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.softAP(ssid, password);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("-- AccessPoint IP address: ");
  Serial.println(myIP);

  Serial.println("-- WiFi-Module started in AP-Mode");
}

void setup() {
  Serial.begin(115200);
  Serial.println("");
  Serial.println("================ Script esp8266_MobileDisplay_1 ================");
  startAsAccessPoint();
  startServer();
}

void loop() {
  server.handleClient();
}

На первом изображении показан результат нажатия на кнопку "Send Draw", а на втором - дополнительного нажатия на кнопку "Send Redraw"

 

 

step962
Offline
Зарегистрирован: 23.05.2011

Совсем забыл: исполняемый файл для Андроида скачивать здесь.

Aleksk
Offline
Зарегистрирован: 08.06.2016

Отличная тема. Жаль на сайте удалили apk для варианта с блютузом.

Очень не хватает загрузки картинки на как фона экрана, что бы сверху рисовать геометрию, точки , линии...

На самом деле такие программы есть, например  AppGosu    https://play.google.com/store/apps/details?id=appgosumcu.arduino.appgosu...

Подозреваю, что в этой программе подключаемый модуль - простой блютуз.

В эту концепцию вывода графики через команды, входят TFT дисплеи  Nextion, а также Waveshare 4.3inch e-paper UART.

 

step962
Offline
Зарегистрирован: 23.05.2011

Поддержка Bluetooth-канала стоит в планах, как и расширение функциональности на работу с изображениями, но в последние два месяца физически нет времени для дальнейшего развития проекта - в апреле стал счастливым обладателем сразу двух внучек. Первые месяцы жизни без остатка занимают все время не только папы-мамы но и всего комплекта бабушек-дедушек. А тут еще и заказчики работой подгрузили...

Если когда появится свободное время, я прежде всего хочу соорудить класс, который позволил бы отойти от генерации управляющих строковых последовательностей "ручками" к более комфортным процедуральным вызовам (примерно как по приведенной ссылке). Ну а затем уже и новые возможности вводить.

Aleksk
Offline
Зарегистрирован: 08.06.2016

Поздравляю! Всех благ.

Нашел ещё подобный проект, управление через блютуз. Проект с открытыми исходниками. Есть практические примеры, например осциллограф из смартфона и ардуины-нано.

 https://github.com/ArminJo/android-blue-display