Подключение Matrix LCD 320x240

Samodelkin
Offline
Зарегистрирован: 07.06.2012

Здравствуйте!

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

Вот ссылка на его даташит http://www.egochina.net.cn/e-shop/ebay/Datasheet/JHD639.pdf

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

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

А яркость подсветки регулировать можете? Попробуйте ей поиграться. Есть мнение, что это позволяет рулить контрастностью в некоторых пределах:
"Многие из ЖК-мониторов имеют сравнительно малый контраст и глубину чёрного цвета. Повышение фактического контраста часто связано с простым усилением яркости подсветки, вплоть до некомфортных значений"
(ЖК-дисплей

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Да вы чё? там же все стандартно! 3-я нога контраст. переменник 10к между питанием и землей, ползунок на 3-й контакт. Ну или (для таких ленивых как я) 3-ю ногу подключаем к выходу с ШИМом, делаем туда analogWrite(), значение в диапазоне 10-150 (подбирается экспериментально) 

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

 Если монохромный дисплей - да, ну а если говорить об RGB-дисплеях 320х240, то в даташитах на их контроллеры даже слова такого нет - "контраст".

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Я перед тем, как советовать, даташит по приведенной ссылке посмотрел. В нем есть контрастность. Если даташит от другого индикатора, то извиняйте. 

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

А мне его загрузить не удалось - вечные песочные часы.

Смотрел по своим RGB-дисплеям.

Samodelkin
Offline
Зарегистрирован: 07.06.2012

AlexFisher пишет:

Да вы чё? там же все стандартно! 3-я нога контраст. переменник 10к между питанием и землей, ползунок на 3-й контакт. Ну или (для таких ленивых как я) 3-ю ногу подключаем к выходу с ШИМом, делаем туда analogWrite(), значение в диапазоне 10-150 (подбирается экспериментально) 

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

Samodelkin
Offline
Зарегистрирован: 07.06.2012

С контрастностью разобрался! Всетаки правильно так, первая нога резистора на "землю", вторая на Vee (-23V), а ползунок на V0. Дисплей заработал, правда текст при выводе на дисплей, вместо одной строки, выводит несколько раз по всему дисплею, буду дальше ковырять...

Samodelkin
Offline
Зарегистрирован: 07.06.2012

Работа продолжается! Дисплей успешно адаптирован к Ардуине и даже работает. Разобрался как выводить графику и текст. Дисплей будет основным элементом для отображения информации. Теперь новая проблема, выводить русский шрифт. Может есть у когонибудь готовые для матричных дисплеев? Немного порыл данную тематику, можно написать свой шрифт с нуля, но уж очень кропотливая работа.

Samodelkin
Offline
Зарегистрирован: 07.06.2012

Вроде со шрифтами чуток разобрался. Теперь новая проблема :)
Очень нужна ваша помощь. Наверное выделять в отдельную тему не буду.

Суть проблемы. Есть две Ардуины Мега, на одной обвес датчиков: 3 температурных, 1 датчик влажности и 1 давления.

Ко второй подключен дисплей, о котором написано выше. Две Ардуины связаны между собой радиомодулем APC220-43, передача данных через сериал порт.

Иду от простого к сложному, теперь вот добрался и до Serial. Проштудировал этот форум и "каша" в голове :)

Во-первых все датчики выдают показания в переменную float.

Радиомодуль сидит на Serial3

На первой датчики:

sensors.getTempCByIndex(0) - Улица

sensors.getTempCByIndex(1) - Комната

sensors.getTempCByIndex(2) - Отопление

H - Влажность

pressure - Давление

Кусок кода на первой:

void setup(){
Serial3.begin(19200);

}

void loop(){

currenttemp=sensors.getTempCByIndex(0);

Serial3.write(currenttemp);

}

На второй:

 

float incomingByte = 0; // переменная для хранения полученного байта

void setup() {
Serial.begin(19200); 
Serial3.begin(19200); // устанавливаем последовательное соединение
}


void loop() {
if (Serial3.available() > 0) {

incomingByte = Serial3.read();
Serial.println(incomingByte);
}}

 

Вторая дуина в монитор выдает температуру в виде 10.00 (например), хотя по факту 10.23, почему так?

помогите разобраться, как мне передать через сериал порт данные ВСЕХ датчиков в виде числа с плавающей запятой (float)? может массив какой надо? Что бы в итоге в мониторе было:

10.34

22.03

и т.д.

Как передать классическое текстовое "Hello World" ?

И еще на принимающей стороне у меня дисплей нужно получить данные таким образом, что бы и сам дисплей "понял".

Вот тестовый пример дисплея:

#include <S1D13700.h>
#include "lucida_font.h"

S1D13700 glcd;

void drawBitmapText(void);


void setup()
{
/*Call the setup routine */
glcd.initLCD();

}

void loop()
{
drawBitmapText();
}


void drawBitmapText(void)
{
/*Create a string variable */
char buf[] = "CATDUINO :)";

/*Clear the screen */
glcd.clearText();
glcd.clearGraphic();

/*specify the column and row address
where the text should be output */
glcd.textGoTo(10,1);

/*Write our string variable to the screen */
glcd.writeText(buf);

/*Write the same string in a different place */
glcd.textGoTo(20,28);
glcd.writeText(buf);

glcd.writeBitmapText(buf,50, 50, LUCIDA_FONT);

}

т.е. данные полученые с сериал порта нужно загнать в этот преславутый buf

Пробовал по всякому, не получается, все время ошибку выдает.

понимаю что тут много понаписал, может получится решить проблему поэтапно, надеюсь на вашу помощь. 
 

leshak
Offline
Зарегистрирован: 29.09.2011

Основная ваша проблема в том, что вы не разобрались чем отличаются типы и как они хранятся в памяти http://arduino.ru/Reference/Float

Цитата:

Переменная типа float занимает 32 бита (4 байта) в памяти.

А Serial.read() и Serial.write() - читают/посылают по одному байту. Следовательно, у вас еще на этапе отсылки ваше число "обрезалось".

Вам нужно, либо разбирать на байты при отправке и слать по одному (а на принимающей опять-таки собирать их в один float), либо при отсылке сделать приведение типа к "это массив из 4-рех байт" (ну и на принимающей соотвественно).

Но....

В данном случае это не самый оптимальный путь. Если у вас на принимающей только задача "вывести" (и не нужно делать каких-то расчетов), то у вас потом встанет вопрос как эту float перевести в текстовую строку(которую нужно полжить в тот самый buff).

Если не стоит цели экономить байты передваемые по сети, то можно сразу передавать строку, возложив "конвертацию числа в строку" на плечи Serial.println отправляющей дуины.

То есть вам нужно, на отправляющей, вместо Serial.write сделать Serial.println

На "принимающей":

  1. Прочитать один символ Serial.read()
  2. Если он не равен \r \n - положить его в массив buff 
  3. Если равен \n - ничего не делать
  4. Если равен \r - вместо него ложим в массив 0. И вызываем наш glcd.writeText(buff);  В buff, к тому времени уже лежит нормальная С-шная строка, которую можно выводить на экран. Ну и, после этого, возвращаем курсор на начало строки, сбрасываем текущий индекс buff на ноль (что-бы опять начать заполнять его с самого начала), ну и ждем следующую строку.

Что-бы легче понять "почему так". Что делает Serial.println - конвертирует число в строку, отсылает строку в Serial побайтово, и добавляет в конце \r - символ перевода каретки, и \n - символ новой строки.

Размер buff, естественно должен быть заведомо больше чем "длина любого числа в виде строки"+1  (что-бы еще было место для нуля - символа конца С-шной строки ).

 Вообщем "принимающая" у вас будет просто брать либые входящие строки и показывать их на экран. А уж число это или какой-то "Привет вася!" - ей все равно. Получится просто LCD который отображает что приходит из Serial.

 

Samodelkin
Offline
Зарегистрирован: 07.06.2012

И еще, мысли вслух. Может нужен алгоритм перадчи?! Например, за каждым датчиком закрепить метку. Передалась буква А ардуина знает, что дальше пойдут данные датчика температуры улицы, далее буква Б данные давления и т.д. Мыслей много, но никак не могу сформулировать... Помогите разобраться. Итогом должно выводиться на дисплей второй ардуины, данные датчиков с первой.

Samodelkin
Offline
Зарегистрирован: 07.06.2012

leshak, да вы правы, мне нужно именно

leshak пишет:

"В данном случае это не самый оптимальный путь. Если у вас на принимающей только задача "вывести" (и не нужно делать каких-то расчетов), то у вас потом встанет вопрос как эту float перевести в текстовую строку(которую нужно полжить в тот самый buff).

Если не стоит цели экономить байты передваемые по сети, то можно сразу передавать строку, возложив "конвертацию числа в строку" на плечи Serial.println отправляющей дуины."

Теперь осталось понять как это:

leshak пишет:

"То есть вам нужно, на отправляющей, вместо Serial.write сделать Serial.println

На "принимающей":
1.Прочитать один символ Serial.read()
2.Если он не равен \r \n - положить его в массив buff
3.Если равен \n - ничего не делать
4.Если равен \r - вместо него ложим в массив 0. И вызываем наш glcd.writeText(buff);  В buff, к тому времени уже лежит нормальная С-шная строка, которую можно выводить на экран. Ну и, после этого, возвращаем курсор на начало строки, сбрасываем текущий индекс buff на ноль (что-бы опять начать заполнять его с самого начала), ну и ждем следующую строку."

Реализовать в коде. Буду пробовать) Хотя пока не совсем понимаю как...

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

Samodelkin пишет:

Реализовать в коде. Буду пробовать) Хотя пока не совсем понимаю как...

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

Вам поможет предварительное прочтение сделующих разделов документации:

Ну и еще можно прочитать string - текстовые строки , что-бы лучше понять что это за ноль такой в конце buff.

 

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Примерно так:

Но попробуйте, все-таки сами написать, не нажимайте сразу "показать код" ;)   Тем более что он тоже может быть ошибочным (я тоже человек)

 

char buff[255]; // 254 - максимально возможная длина строки
byte idx=0; // текущий индекс в buff, новый символ будет ложить по этому индексу
void setup(){
  Serial3.begin(19200);
}

void loop(){
  if(Serial3.available()){
      char ch=Serial3.read();// прочитали символ
      switch(ch){
        case '\r':break; // игнорим
        case '\n': // конец строки
                   buff[idx]=0; // заносим в буфер признак конца строки
                   
                   // Тут выводим наш buff
                   //LCD.WriteText(buff); перевели курсор и т.п.
                  // или
                  // Serial.println(buff);
                  
                   idx=0; // приготовились заново писать в начало буффера
                   break;
         default: 
                   buff[idx]=ch; // просто запомнили прочитанынй символ в буффер
                   idx++; // увеличили счетчик
                   
      }
  }
}

 

Samodelkin
Offline
Зарегистрирован: 07.06.2012

leshak, большое спасибо за ответы. Я сторонник разобраться сам, что бы поэтапно разложить все по полочкам. По мере буду выкладывать свои "каракули", надеюсь вы поможете сделать работу над ошибками :)

leshak
Offline
Зарегистрирован: 29.09.2011

Samodelkin пишет:

 Я сторонник разобраться сам, что бы поэтапно разложить все по полочкам. 

Это сразу видно по тому что вы разбили свою задачу на три отдельные части. Причем тестовые. Отправляющая (причем только один датчик), принимающая (которая выводит отладку в Serial) и отдельно вывод на экран. А не, как делают очень многие, подключили все имеющиеся в квартире датчики, 15-ть кнопок, три экрана, две страницы хитрой "бизнес логики", а потом "ой... не работает.... найдите ошибку" :)

IMHO ваш порядок действий - самый правильный. Раздробить задачу. Упростить части "до примитива". Отладить по отдельности. А уж потом "собирать все вместе, усложнять".

Так и самому "локализировать проблему" - гораздо проще,решения гуглить легче. Да и нам, чем-то помочь на форуме, - намного реальней.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

leshak пишет:

 Примерно так:

Но попробуйте, все-таки сами написать, не нажимайте сразу "показать код" ;)   Тем более что он тоже может быть ошибочным (я тоже человек)

... 

Еще хорошо помогает разбор стандартного примера StringToInt - там есть почти все, что нужно.

Samodelkin
Offline
Зарегистрирован: 07.06.2012

leshak, спасибо вам за ссылки и привиденный пример кода, он оказался на 100% рабочим! Вобще всякий раз удивляюсь, как вы граматно, корректно, втолковываете куда надо грести)) Почти в каждой теме, просящий помощи получает ее. Вы тратите свободное время на ответы, за что вам большое спасибо. А администрации "Arduino.ru" пора вам доплачивать :)

Возвращаясь к теме. Мне как не программеру пока тяжеловато понять двумерные массивы, строки и т.д. да и времени не было на свежую голову почитать. Буду стараться вникнуть.

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

На отправляющей стороне:

Serial3.println ('a');
Serial3.println(sensors.getTempCByIndex(2)); // Комната
Serial3.println ('b');
Serial3.println(sensors.getTempCByIndex(1)); // Отопление
Serial3.println ('c');
Serial3.println(H); // Влажность %
Serial3.println ('d');
Serial3.println(mint2); // Min T на улице
Serial3.println ('e');
Serial3.println (maxt2); // Max T на улице
Serial3.println ('h');
Serial3.println (mint); // Min T в комнате
Serial3.println ('x');
Serial3.println(maxt); // Max T в комнате
Serial3.println ('y');
Serial3.println (sensors.getTempCByIndex(0)); // Улица
Serial3.println ('g');
Serial3.println(davlenie2); // Давление мм.рт.ст
Serial3.println ('f');

На принимающей стороне:

if(Serial3.available()){
      char ch=Serial3.read();// прочитали символ
      switch(ch){
        case '\r':break; // игнорим
        case '\n': // конец строки
                   buff[idx]=0; // заносим в буфер признак конца строки
                   idx=0; // приготовились заново писать в начало буффера
                   break;
         case 'a': // Перевод строки
                   glcd.writeBitmapText(buff,95, 30, LUCIDA_FONT);
                   break;
         case 'b': // Перевод строки
                   glcd.writeBitmapText(buff,120, 90, LUCIDA_FONT);
                   break;
         case 'c': // Перевод строки
                   glcd.writeBitmapText(buff,150, 150, LUCIDA_FONT);
                   break;
         case 'd': // Перевод строки
                   glcd.writeBitmapText(buff,150, 180, LUCIDA_FONT);
                   break;
         case 'f': // Перевод строки
                   glcd.writeBitmapText(buff,150, 210, LUCIDA_FONT);
                   break;
         case 'e': // Перевод строки
                   glcd.writeBitmapText(buff,75, 60, LUCIDA_FONT);
                   break;
         case 'h': // Перевод строки
                   glcd.writeBitmapText(buff,232, 60, LUCIDA_FONT);
                   break;          
         case 'x': // Перевод строки
                   glcd.writeBitmapText(buff,75, 120, LUCIDA_FONT);
                   break;
         case 'y': // Перевод строки
                   glcd.writeBitmapText(buff,232, 120, LUCIDA_FONT);
                   break;         
         case 'g': // Перевод строки
                   glcd.writeBitmapText(buff,95, 30, LUCIDA_FONT);
                   break;
         default: 
                   buff[idx]=ch; // просто запомнили прочитанынй символ в буффер
                   idx++; // увеличили счетчик    
      }

 

Получилось наверное топорно :)