Подключение LED дисплея SHD0032 к ардуино - Arduino

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Gifrom
Открыл глаза
Сообщения: 40
Зарегистрирован: Пт дек 05, 2014 09:28:39

Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение Gifrom »

Только начинаю разбираться с программированием и ардуино. Не получается нормально запустить дисплей http://www.chipdip.ru/product/shd0032g/ . Что не пробовал, цифры горят как минимум попарно, а как максимум абракадаброй. Спрашивал на разных форумах, но все темы затухли. Для начала моя цель - просто научится выводить на дисплей цифры которые захочу.
Самый рабочий вроде этот код

Код: Выделить всё

#define PIN_E 7 // enable
#define PIN_L 8 // latch
#define PIN_C 9 // clock
#define PIN_D 10// data
 
#define SYMBOLS_ARRAY_LENGTH 12 //Длина массива символов
unsigned char Symbols[SYMBOLS_ARRAY_LENGTH]={ // Массив символов индикатора
  252, // 0
  96,  // 1
  218, // 2
  242, // 3
  102, // 4
  182, // 5
  190, // 6
  224, // 7
  254, // 8
  246, // 9
  1,   // .
  2    // -
};
 
void setup()
{
  pinMode(PIN_E, OUTPUT);
  pinMode(PIN_L, OUTPUT);
  pinMode(PIN_C, OUTPUT);
  pinMode(PIN_D, OUTPUT);
  digitalWrite(PIN_L, LOW); // сигнал защелки вниз
  digitalWrite(PIN_E, LOW); // включаем сегменты
  digitalWrite(PIN_C, LOW); // тактовый сигнал вниз
}
 
void loop()
{
  // показываем на дисплее счетчик
  for(int i = 0; i < 10; i++)
  {
    unsigned long value = GetValue(i, i, i, i);
    WriteReg(value);
  }
}
 
// пишем в регистр сразу 32 разряда
// пишем в регистр сразу 32 разряда
void WriteReg(unsigned long value)
{
  for(int i = 0; i < 32; i++)      // перебираем разряды
  {
    int data = (value >> i) & 0x1; // берем очередной разряд
    digitalWrite(PIN_C, LOW);     // тактовый сигнал вверх
    digitalWrite(PIN_D, data);     // устанавливаем сигнал данных
    digitalWrite(PIN_C, HIGH);      // тактовый сигнал вниз
  }
  digitalWrite(PIN_L, HIGH);       // защелку вверх
  digitalWrite(PIN_L, LOW);        // защелку вниз
  delay(500);
}
 
// передаем числа, получаем на выходе код для их отображения
unsigned long GetValue(byte s1, byte s2, byte s3, byte s4)
{
  return
    (unsigned long)(Symbols[s1] << 0) |
    (unsigned long)(Symbols[s2] << 8) |
    (unsigned long)(Symbols[s3] << 16) |
    (unsigned long)(Symbols[s4] << 24);
}

Вот результат
https://youtu.be/fv6uQGRCmX0
Подскажите пожалуйста где может быть ошибка.
Аватара пользователя
Gisteresis
Друг Кота
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение Gisteresis »

Вместо массива цифр, заведите всего 1 сегмент. Вместо цифры 0, сегмент a. Вместо цифры 1, сегмент b. И так далее. Потом вместо тела программы просто попробуйте выводить сегменты, все ли правильно загорается?
Если правильно, тогда приступаем к формированию цифр, таким же макаром, добиваемся правильного отображения цифр.
Далее проверяем алгоритм дробления числа на декады.
Gifrom
Открыл глаза
Сообщения: 40
Зарегистрирован: Пт дек 05, 2014 09:28:39

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение Gifrom »

Код: Выделить всё

#define PIN_E 7 // enable
#define PIN_L 8 // latch
#define PIN_C 9 // clock
#define PIN_D 10// data
 
#define SYMBOLS_ARRAY_LENGTH 12 //Длина массива символов
unsigned char Symbols[SYMBOLS_ARRAY_LENGTH]={ // Массив символов индикатора
 252, // 0
  96,  // 1
  218, // 2
  242, // 3
  102, // 4
  182, // 5
  190, // 6
  224, // 7
  254, // 8
  246, // 9
  1,   // .
  2    // -
};
 
void setup()
{
  pinMode(PIN_E, OUTPUT);
  pinMode(PIN_L, OUTPUT);
  pinMode(PIN_C, OUTPUT);
  pinMode(PIN_D, OUTPUT);
  digitalWrite(PIN_L, LOW); // сигнал защелки вниз
  digitalWrite(PIN_E, LOW); // включаем сегменты
  digitalWrite(PIN_C, LOW); // тактовый сигнал вниз
}
 
void loop()

  {
    unsigned long value = GetValue(4, 3, 2, 1);
    WriteReg(value);
  }

 
// пишем в регистр сразу 32 разряда
// пишем в регистр сразу 32 разряда
void WriteReg(unsigned long value)
{
  for(int i = 0; i < 32; i++)      // перебираем разряды
  {
    int data = (value >> i) & 0x1; // берем очередной разряд
    digitalWrite(PIN_C, LOW);     // тактовый сигнал вверх
    digitalWrite(PIN_D, data);     // устанавливаем сигнал данных
    digitalWrite(PIN_C, HIGH);      // тактовый сигнал вниз
  }
  digitalWrite(PIN_L, HIGH);       // защелку вверх
  digitalWrite(PIN_L, LOW);        // защелку вниз
 
}
 
// передаем числа, получаем на выходе код для их отображения
unsigned long GetValue(byte s1, byte s2, byte s3, byte s4)
{
  return
    (unsigned long)(Symbols[s1] << 0) |
    (unsigned long)(Symbols[s2] << 8) |
    (unsigned long)(Symbols[s3] << 16) |
    (unsigned long)(Symbols[s4] << 24);
}

Чтобы не делал, два первых сегмента либо вобще не горят-если на все подать единицу, либо с другими цифрами горят полностью все разряды. Этот код у меня выдаёт вместо 1234 - "8. 8.34" . Назначал по одному разряду, то же самое, в последних двух сегментах всё правильно, а в перфых восьмёрки или темнота
kone4nik
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Ср окт 21, 2015 06:50:33
Откуда: Киров

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение kone4nik »

Попробуйте в функцию WriteReg передавать уже готовое число. Такое впечатление, что unsigned long длиной 2 байта. ИМХО, т.к. я не спец в с для Arduino
Gifrom
Открыл глаза
Сообщения: 40
Зарегистрирован: Пт дек 05, 2014 09:28:39

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение Gifrom »

Записал нужные сектора вручную в обратном порядке в двоичное число, потом перевёл его в десятичное получил

Код: Выделить всё

void loop()

  {
    unsigned long value = 1624961638;
    WriteReg(value);
  }

теперь горит так как нужно. Только как всё это теперь автоматизировать. Не считать же вручную
kone4nik
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Ср окт 21, 2015 06:50:33
Откуда: Киров

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение kone4nik »

Я бы сделал отдельно функцию вывода в регистр одного разряда, после вывода всех четырёх разрядов подаём сигнал защёлки. Похоже какая-то некорректность с работой 32-х разрядных чисел в функции GetValue
Аватара пользователя
Gisteresis
Друг Кота
Сообщения: 4732
Зарегистрирован: Ср сен 18, 2013 10:08:26
Откуда: Санкт-Петербург

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение Gisteresis »

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

****

Сам посмотрел, вообще странно, пишут что 4 байта
http://atmel.ucoz.ru/publ/unsigned_long/1-1-0-46

Операции сдвига не могут выпихивать число за пределы byte а потом присваивать его ulong?
Проверьте, поменяйте тип "unsigned char Symbols[SYMBOLS_ARRAY_LENGTH]={ // Массив символов индикатора" на ulong.
OKF
Это не хвост, это антенна
Сообщения: 1385
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение OKF »

Давеча УДАЛЁННО запустил человеку вышеуказанный дисплей.
Прилагаю требуемые файлы. Надеюсь разберётесь.
Вложения
spi.h
(3.01 КБ) 411 скачиваний
spi.c
(1.11 КБ) 635 скачиваний
sled.h
(368 байт) 672 скачивания
sled.c
(1.99 КБ) 717 скачиваний
Gifrom
Открыл глаза
Сообщения: 40
Зарегистрирован: Пт дек 05, 2014 09:28:39

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение Gifrom »

Покуда не разобрался, почему-то если сделать

Код: Выделить всё

{
    int i;
    i = 1624961638;
  unsigned long value = i;
  WriteReg(value);
}

то выходит 8.8.34
а если

Код: Выделить всё

{
  unsigned long value = 1624961638;
 WriteReg(value);
}

то 1234
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение arkhnchul »

дык 1624961638 в int не влазит
Gifrom
Открыл глаза
Сообщения: 40
Зарегистрирован: Пт дек 05, 2014 09:28:39

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение Gifrom »

Запустился как надо вот такой код. Сегменты по одному просто отсылать нужно было

Код: Выделить всё

#define PIN_E 7 // enable
#define PIN_L 8 // latch
#define PIN_C 9 // clock
#define PIN_D 10// data

#define SYMBOLS_ARRAY_LENGTH 18 //Длина массива символов
unsigned char Symbols[SYMBOLS_ARRAY_LENGTH]={ // Массив символов индикатора
  252, // 0
  96,  // 1
  218, // 2
  242, // 3
  102, // 4
  182, // 5
  190, // 6
  224, // 7
  254, // 8
  246, // 9
  238, // A
  62,  // B
  156, // C
  122, // D
  158, // E
  142, // F
  1,   // .
  2    // -
};

void setup()
{
  pinMode(PIN_E, OUTPUT);
  pinMode(PIN_L, OUTPUT);
  pinMode(PIN_C, OUTPUT);
  pinMode(PIN_D, OUTPUT);
  digitalWrite(PIN_L, LOW); // сигнал защелки вниз
  digitalWrite(PIN_E, LOW); // включаем сегменты
  digitalWrite(PIN_C, LOW); // тактовый сигнал вниз
  Serial.begin(9600);
}

void loop()
{
  // показываем на дисплее счетчик
  for(int i = 0; i < SYMBOLS_ARRAY_LENGTH; i++)
  {
    WriteReg(i, i, i, i);
    WriteLatch();
    Serial.println(i);
  }
}

// пишем в регистр 8 разрядов
void WriteReg(byte s1, byte s2, byte s3, byte s4)
{
  byte s[4] = {Symbols[s1], Symbols[s2], Symbols[s3], Symbols[s4]};
  for (int b = 0; b < 4; b++)
  {
    byte value = s[b];
    for(int i = 0; i < 8; i++)      // перебираем разряды
    {
      int data = (value >> i) & 0x1; // берем очередной разряд
      digitalWrite(PIN_C, LOW);     // тактовый сигнал вверх
      digitalWrite(PIN_D, data);     // устанавливаем сигнал данных
      digitalWrite(PIN_C, HIGH);      // тактовый сигнал вниз
    }
  }
}

// пишем защелку
void WriteLatch()
{
  digitalWrite(PIN_L, HIGH);       // защелку вверх
  digitalWrite(PIN_L, LOW);        // защелку вниз
  delay(1000);
}

Буду дальше придумывать как скорость расчитанную по датчику холла на него выводить. Чтобы горела точка (для показа десятых долей километра) нужно чтобы в третий сегмент всегда в первый бит значение 1 подставлялось. При любом числе.
Gifrom
Открыл глаза
Сообщения: 40
Зарегистрирован: Пт дек 05, 2014 09:28:39

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение Gifrom »

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

Код: Выделить всё

 dtostrf(speed, 3, 1, myStr8);  // выводим в строку myStr 3 до запятой, один разряд после запятой
  MyStr = myStr8
, т.к даже если туда подставить значение дисплей показывает нули, а вот если прировнять

Код: Выделить всё

char c = myStr8[0];
числу, то выведет его корректно.

Код: Выделить всё

#define PIN_E 7 // enable
#define PIN_L 8 // latch
#define PIN_C 9 // clock
#define PIN_D 10// data
unsigned long cur_ms = 0; //переменная для отслеживания натикавших миллисекунд с момента пуска МК
unsigned long prev_ms = 0; //переменная для вычисления отрезков времени
int ms = 0; //сам отрезок времени
int m = 0; //пройденное расстояние
int speed = 0; //переменная для хранения скорости
String MyStr;
char myStr8[10];
char c = myStr8[0];
char d = myStr8[1];
char e = myStr8[2];
char f = myStr8[3];
const   byte   Sect_Size   =   4;   //   Четырёхразрядная секция индикатора
const   byte   Byte_Size   =   8;   //   Число бит в байте

#define SYMBOLS_ARRAY_LENGTH 20 //Длина массива символов
unsigned char Symbols[SYMBOLS_ARRAY_LENGTH] = { // Массив символов индикатора
  252, // 0
   96, // 1
  218, // 2
  242, // 3
  102, // 4
  182, // 5
  190, // 6
  224, // 7
  254, // 8
  246, // 9
  238, // A
   62, // B
  156, // C
  122, // D
  158, // E
  142, // F
  188, // G
  110, // H
    1, // .
    2  // -
};

void setup()

{
  pinMode(20, INPUT); //включаем 20й порт на Ардуино Мега2560 на чтение
digitalWrite(20, HIGH);  //включаем подтягивающий резистор
attachInterrupt(3, odom, RISING); //включаем внешнее прерывание
  pinMode(PIN_E, OUTPUT);
  pinMode(PIN_L, OUTPUT);
  pinMode(PIN_C, OUTPUT);
  pinMode(PIN_D, OUTPUT);
  digitalWrite(PIN_L, LOW); // сигнал защёлки вниз
  digitalWrite(PIN_E, LOW); // включаем сегменты
  digitalWrite(PIN_C, LOW); // тактовый сигнал вниз
  Serial.begin(9600);
}
void odom() {
    m++; //добавляем 1 при каждом срабатывании
}

void loop()

{
   dtostrf(speed, 3, 1, myStr8);  // выводим в строку myStr 3 до запятой, один разряд после запятой
  MyStr = myStr8;

 
 
  cur_ms = millis(); //сколько прошло мс с момента включения
    ms = cur_ms - prev_ms; //сколько прошло мс с последнего расчета
    if (ms > 500)
        prev_ms = cur_ms; //ставим метку когда было срабатывание
        speed = m * 3600 / ms; //вычисляем скорость км в час по кол-ву пройденных метров за отрезок времени ms
        m = 0; //обнуляем пройденное расстояние
        ms=0; //обнуляем отрезок времени
   
  unsigned char Segments [Sect_Size];
  byte          Digit    [Sect_Size];
 
  for ( int i = 0; i < Sect_Size; i++ )
  {
   
   
  }
  // показываем на дисплее счетчик
  Digit [3] = c;
  Digit [2] = d;
  Digit [1] = e;
  Digit [0] = f;
 
 /* for ( int i = 0; i < Sect_Size; i++ )
  {
    Segments [i] = Symbols [ Digit [i] ];
  } ;
  Segments [3] = Segments [3] + 1;
 */
  {
    WriteReg( Digit [0], Digit [1], Digit [2], Digit [3] );
    WriteLatch();
    Serial.println(Digit [1]);
   
  }
}

// пишем в регистр (Byte_Size = 8) разрядов
void WriteReg(byte s1, byte s2, byte s3, byte s4)
{
/*
  byte shift = 16;
  byte s[Sect_Size] = { Symbols [shift+0], Symbols [shift+1],
                        Symbols [shift+2], Symbols [shift+3] };
*/
  byte s[Sect_Size] = {Symbols [s1], Symbols [s2], Symbols [s3], Symbols [s4]};
  for ( int b = 0; b < Sect_Size; b++ )
  {
    byte value = s[b];                   // | ( b == 0 ? 0x1 : 0x0 );
   
    if (b == 1) value |= 0x1;            // Позиция (b == 2) разделительной точки
   
    for( int i = 0; i < Byte_Size; i++ ) // перебираем разряды
    {
      int data = (value >> i) & 0x1; // берём очередной разряд
      digitalWrite(PIN_C, LOW);      // тактовый сигнал вверх
      digitalWrite(PIN_D, data);     // устанавливаем сигнал данных
      digitalWrite(PIN_C, HIGH);     // тактовый сигнал вниз
    }
  }
}

// пишем защёлку
void WriteLatch()
{
  digitalWrite(PIN_L, HIGH);       // защёлку вверх
  digitalWrite(PIN_L, LOW);        // защёлку вниз
  delay(1000);
}
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Подключение LED дисплея SHD0032 к ардуино - Arduino

Сообщение arkhnchul »

суйте портянки кода под спойлер

[uquote="Gifrom",url="/forum/viewtopic.php?p=3260283#p3260283"]

Код: Выделить всё

  MyStr = myStr8
[/uquote]
нельзя просто так взять и присвоить значение переменной типа "указатель на чар" другой переменной с типом "объект String"

Код: Выделить всё

MyStr = String(myStr8)
Ответить

Вернуться в «Разные вопросы по МК»