#1 Re: Проекты » Диммирование LED-матрицы по Bluetooth на Digispark-ATTiny85 » 2019-01-30 18:45:09

Вячеслав Азаров пишет:

Класс String и ту же read(). https://www.arduino.cc/reference/en/lan … ingobject/ Это удобнее всего.

Входное значения у меня лежит в String .
Проблема в том, что вместо ASCII-символа считывается ASCII-код, а мне нужно получать именно символ.
К примеру, я отправляю единицу, и на выходе она и должна придти, а не 48. Как в этом случае менять код, чтобы приняло так, как я хотел?

И , похоже, это не единственная проблема. Каждый символ отправится отдельно, даже если я исправлю проблему с кодами ASCII.
В этой статье , когда я делал под Arduino, рекомендовали для решения readString, который я в своей ситуации не могу использовать, мне доступен только read, который только один символ читать и будет. Есть альтернатива readString'у?

#2 Re: Проекты » Диммирование LED-матрицы по Bluetooth на Digispark-ATTiny85 » 2019-01-30 18:04:22

Вячеслав Азаров пишет:
artm пишет:

В чём именно неверен?

Метод read() считывает только один ASCII а не всю строку. А все остальное - следствие этого.

А как тогда считать именно строку? Что использовать?

#3 Re: Проекты » Диммирование LED-матрицы по Bluetooth на Digispark-ATTiny85 » 2019-01-30 17:51:12

Вячеслав Азаров пишет:

Ищите конец строки и начало новой, в линукс это символ "\n", после этого, считывете требуемые вам символы в пустую строку и делаете преобразование последней, в число.

Здесь проблема немного иначе. Значения не склеиваются , они вместо строки просто передаются в виде ASCII - кодов каждой цифры.
И ещё надо учитывать отсутствие методов readString/readStringUntil

Вячеслав Азаров пишет:

А алгоритм в вашей программе неверен.

В чём именно неверен?

#4 Проекты » Диммирование LED-матрицы по Bluetooth на Digispark-ATTiny85 » 2019-01-30 17:12:41

artm
Ответов: 8

Здравствуйте.
Относительно недавно я занимался реализацией управления яркостью LED-матрицы по Bluetooth посредством GUI и создавал тему на форуме касательно проблемы получения значений в этом проекте. Проблему с этим я решил и всё заработало.

Вскоре для практики я решил перенести этот маленький проект на Digispark ATtiny85.
Задача заключается в том, чтобы по Bluetooth с телефона отправлять значения от 0 до 255 и в зависимости от значения менять яркость. На данный момент я использую в качестве приложения для управления Bluetooth Terminal.
Так как изначально у Тиньки отсутствует UART, класс Serial, через который я получал данные с HC-06 на Ардуинке, уходит в небытие, поэтому я воспользовался библиотекой Digispark SoftSerial в качестве альтернативы.

Написал вот такой скетч:

#include <SoftSerial.h> //Библиотека для программного UART 
#include <TinyPinChange.h> //зависимость библиотеки SoftSerial
#define RX 3 //P3 на Digispark в качестве RX 
#define TX 2 //P2 на Digispark в качестве TX
int led=4; //к P4 на Digispark подключен + транзистора, к которому подключена LED-матрица
SoftSerial bluetooth(TX, RX); //объявление 

int brightness; //переменная для преобразованного значения
String fadeAmount; //для входных данных

void setup() {
  pinMode(led, OUTPUT); //устанавливаем P4 как выход
  bluetooth.begin(9600);  //начинаем работу программного Serial на скорости 9600 бод
  digitalWrite(led, LOW); //выключаем LED-матрицу
  delay(10); 
}

void loop() {
  if(bluetooth.available()) //если программный Serial доступен
  { 
    fadeAmount = bluetooth.read(); //считываем отправленное по BT значение 
    bluetooth.println("In: "+ fadeAmount);  //Вывод входного значения. 
    brightness = fadeAmount.toInt();  //преобразование данных в число
    bluetooth.print("Out: "); 
    bluetooth.println(brightness); //вывод преобразованных данных
    if(brightness > 0) //если значение больше ноля:
      analogWrite(led, brightness);  //меняем яркость в соответствии с значением ползунка
  }
}

Пришлось отказаться от методов readString/readStringUntil , т.к. в SoftSerial они отсутствуют, и использовать read().
Впоследствии я столкнулся с проблемой, которую я и решал с помощью Serial.readString() на Arduino : значения передаются в формате ASCII-кода символа, который я отправил. Если больше одного символа- каждый отправляется по очереди.
Вот вывод при попытке менять яркость через терминал(Уточню, что комментарии в треугольных скобках я дописывал не при отправке значений, а в этом вопросе):

>: 0 <после ">:"  показано значение из моего ввода>
In: 48 <In - это значение, которое пришло и ещё не обработалось. Здесь вместо 0 получился 48>
Out: 48 <Out-Преобразованное в целое число и отправленное на LED-матрицу значение>
>:10 
In: 49 <Отправилась единица отдельно в коде 49(?)>
Out: 49
In: 48 <тут отправился 0, как 48. Каждое число разделяется и отправляется по очереди.>
Out:48
>:250 <здесь 2, 5 и 0 тоже отправляются по отдельности>
In: 50 <2>
Out: 50
In:53 <5>
Out: 53
In: 48
Out: 48 <0>

[Видео, в котором показано, как всё прорабатывает]

Самое странное, что при первом срабатывании яркость больше не меняется ( по-крайне мере, если смотреть на LED-матрицу ). Всё остаётся на месте. 


pwm.jpg
                                        Схема всей моей конструкции

Как можно решить эту проблему с передачей значения?
Буду искренне благодарен за помощь.

#5 Re: Проекты » Управление яркостью LED-матрицы по Bluetooth с помощью GUI » 2019-01-19 18:35:40

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

Итак, вот сам скетч:

int led = 11;
int brightness; //переменная для преобразованного значения
String fadeAmount; //для входных данных


void setup() {
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  Serial.begin(9600);
  delay(10);
}

void loop() {
  if (Serial.available()) { //если монитор порта доступен:
    fadeAmount = Serial.readStringUntil('\n'); //считываем значение с монитора порта до новой строки (String). 
    Serial.print("In:"); 
    Serial.println(fadeAmount); //вывод данных, которые отправило приложение

    brightness = fadeAmount.toInt();  //преобразование данных в число

    Serial.print("Out:");
    Serial.println(brightness); //вывод преобразованных данных
    analogWrite(led, brightness); //меняем яркость в соответствии с значением ползцнка

  }
}

Код приложения:
final.jpg

Файл проекта, вдруг кому понадобится:
https://drive.google.com/file/d/1lPc0lH … sp=sharing

APK-файл: https://drive.google.com/file/d/1arkKGJ … sp=sharing

Видео с показом работы управления:
https://www.youtube.com/watch?v=o4xs69bpzzo


Архив со всем вместе (скетч, файл проекта, APK, видео, картинка со схемой подключения HC-06 и README-файл с инструкциями):
https://drive.google.com/file/d/1MaiUuP … sp=sharing

Ещё раз благодарю за помощь.

#6 Re: Проекты » Управление яркостью LED-матрицы по Bluetooth с помощью GUI » 2019-01-19 12:11:04

Вот запись с вывода:

In:5.1;12.75;20.4;28.05;35.7;43.35;51;56.1;
Out:5
In:61.2;66.3;68.85;71.4;73.95;76.5;79.05;84.15;89.25;96.9;102;109.65;117.3;130.05;145.35001;163.2;178.5;188.7;198.89999;209.10001;216.75;
Out:61

In - значение, которое отправляет приложение
Out - преобразовано уже на Ардуино

В приложении я добавил, что-бы каждое значение было с маркером ";".

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

Здесь блок, отвечающий за смену ползунка и отправки значений. Возможно есть, что подправить:
sshot-2019-01-19-11-04-40.jpg

#7 Re: Проекты » Управление яркостью LED-матрицы по Bluetooth с помощью GUI » 2019-01-17 21:13:10

renoshnik пишет:
artm пишет:

Простите, ко мне не доходит. Что  имеется ввиду под маркером? Как именно его делать?

http://wikihandbk.com/wiki/Arduino:%D0%A1%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D1%87%D0%BD%D0%B8%D0%BA_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B0_Arduino/%D0%91%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B8/Serial/readStringUntil()

Завершает свою работу, если наткнется на терминальный символ или если выйдет время.
terminator — искомый символ (char)

Отредактировал скетч:

int led = 11;
int brightness;
String fadeAmount;


void setup() {
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  Serial.begin(9600);
  delay(10);
}

void loop() {
  if (Serial.available()) {
    fadeAmount = Serial.readStringUntil(";");
    Serial.print("In:");
    Serial.println(fadeAmount);

    brightness = fadeAmount.toInt();

    Serial.print("Out:");
    Serial.println(brightness);
    analogWrite(led, brightness);

  }
}

В коде приложения добавил к значениям ползунка маркер ";" . Вроде-бы я понял суть работы функции, но  , как бы ни было очевидно, отправляется первое значение, с которого я начал. Как считывать именно последнее?
(Сразу извиняюсь за большое количество вопросов)

#8 Re: Проекты » Управление яркостью LED-матрицы по Bluetooth с помощью GUI » 2019-01-17 13:28:51

Простите, ко мне не доходит. Что  имеется ввиду под маркером? Как именно его делать?

#9 Re: Проекты » Управление яркостью LED-матрицы по Bluetooth с помощью GUI » 2019-01-17 11:17:02

renoshnik пишет:

Вопрос:
Вы думаете, что все кинутся устанавливать App Inventor чтобы посмотреть, что вы там на программировали ?

Его необязательно скачивать, достаточно залогиниться на сайте под аккаунтом Гугла и импортировать проект. Я просто закинул исходники того приложения.
Если нет возможности посмотреть-кидаю ссылку на скриншот кода: https://drive.google.com/file/d/1fi6RRU … p=drivesdk

renoshnik пишет:

  совет - используйте readStringUntil() ...

Прочитав документацию, я так понял, что функция считывает значение, пока я не получу нужное.
Но мне нужно ждать значения от 0 до 255, а не ожидать какое-то определенное. Как в этом случае сделать?

#10 Проекты » Управление яркостью LED-матрицы по Bluetooth с помощью GUI » 2019-01-16 23:27:00

artm
Ответов: 10

[Решено, см. последнее сообщение]
Здравствуйте.
Есть небольшой проект. Заключается он в том, что-бы управлять  яркостью LED-матрицы с помощью ШИМ по Bluetooth с телефона, используя небольшое приложение с ползунком для отправления значений от 0 до 255.
В качестве Bluetooth-модуля я использую HC-06, а плата - Arduino Uno.

Есть готовый скетч для управления яркостью:

int led = 11;
int brightness;
String fadeAmount;


void setup() {
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  Serial.begin(9600);
  delay(10);
}

void loop() {
  if (Serial.available()) {
    fadeAmount = Serial.readString();
    if (fadeAmount != "-1")
    {
      Serial.print("In:");
      Serial.println(fadeAmount);

      brightness = fadeAmount.toInt();

      Serial.print("Out:");
      Serial.println(brightness);
      analogWrite(led, brightness);
    }
  }
}

Приложение с GUI я делал на App Inventor. Состоит оно из

  • ListWidget для отображения сопряженных устройств

  • Кнопки для их поиска

  • Ползунка с диапазоном значений 0-255

  • Блоков горизонтального и вертикального расположения


Ссылка на файл проекта App Inventor:  https://drive.google.com/file/d/1MaHsFE … sp=sharing

Теперь непосредственно к самой проблеме:
После успешного подключения я плавно меняю положение ползунка. При каждом его смещении, при этом не отпуская палец, значения отправляются мгновенно.  Но вместо того, чтобы отослать значение, на котором я отпустил палец, они отправляются мгновенно и склеиваются в одно огромное значение, которое отсылается по Bluetoooth. В результате, Arduino обрабатывает значение, отсылает на пин 11 и после этого яркость стает совсем противоположной тому, что должно было придти.

Вопрос:
Как сделать отправку значений только после того, как я отпущу палец с ползунка?

#11 Re: Проекты » Bluetooth HC-06 » 2019-01-16 19:27:47

Здравствуйте.
Есть небольшой проект. Заключается он в том, что-бы управлять  яркостью LED-матрицы с помощью ШИМ по Bluetooth с телефона, используя небольшое приложение с ползунком для отправления значений от 0 до 255.

Есть готовый скетч для управления яркостью:

int led = 11;
int brightness;
String fadeAmount;


void setup() {
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  Serial.begin(9600);
  delay(10);
}

void loop() {
  if (Serial.available()) {
    fadeAmount = Serial.readString();
    if (fadeAmount != "-1")
    {
      Serial.print("In:");
      Serial.println(fadeAmount);

      brightness = fadeAmount.toInt();

      Serial.print("Out:");
      Serial.println(brightness);
      analogWrite(led, brightness);
    }
  }
}

Приложение с GUI я делал на App Inventor. Состоит оно из

  • ListWidget для отображения сопряженных устройств

  • Кнопки для их поиска

  • Ползунка с диапазоном значений 0-255

  • Блоков горизонтального и вертикального расположения


Ссылка на файл проекта App Inventor:  https://drive.google.com/file/d/1MaHsFE … sp=sharing

Теперь непосредственно к самой проблеме:
После успешного подключения я плавно меняю положение ползунка. При каждом его смещении, при этом не отпуская палец, значения отправляются мгновенно.  Но вместо того, чтобы отослать значение, на котором я отпустил палец, они отправляются мгновенно и склеиваются в одно огромное значение, которое отсылается по Bluetoooth. В результате, Arduino обрабатывает значение, отсылает на пин 11 и после этого яркость стает совсем противоположной тому, что должно было придти.

Вопрос:
Как сделать отправку значений только после того, как я отпущу палец с ползунка?

Подвал раздела