Вывод информации на 4 разрядный 7сегментный индикатор при помощи двух 74hc595

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

http://arduino.ru/Reference/Serial/Available

  if (gsm.available()) {
    while (gsm.available()) {
      .
      .
      .
      .
    }
.
.
.
}

 

mag155
Offline
Зарегистрирован: 21.12.2017

Получилось вот так 

void loop() {
  

 
if (radio.available()) {
while (radio.available()) {
  val = radio.read();
} 
   float numbers[] = {val}; 
      Serial.println(val);
  
 unsigned long currentMillis = millis();
   
 if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
   
  getDigits(numbers[numindex]);
    numindex += 1;
 
    if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
  }
 
  displayMessage(arr);

}
}

 

mag155
Offline
Зарегистрирован: 21.12.2017

Значение через val не могу вывести больше 250 ???

alexeko
Offline
Зарегистрирован: 03.01.2014

mag155, дайте определение динамической индикации, а не выжимайте из AVR невозможного. Если динамику делать на ардуинке, то считаем: время затухания светодиода, после того как убираете напряжение и скорость обновления (полного прохода) по коду. Тут, как писано в старых учебниках, надо, при большом количестве диодов, повышать напряжение, что бы горели лучше. Но, индикатор может сгореть, если что то не так пойдет. Если мигает - результат большого времени работы программного кода. 

Есть отдельные драйвера, которые сами делают индикацию, а ардуинка подает только данные для определенного диода. 

А, так получается, Вы пытаетесь что выжать из ее максимума. Я не хочу Вас обидеть. Просто надо искать ошибки не только кода, но и железа.

 

 

mag155
Offline
Зарегистрирован: 21.12.2017

Точнее передать только 0-250

 val = analogRead(potent_pin);    
 val = map(val, 0, 1023, 0, 1023);  
  //val = constrain(val, 0, 250);      
      Serial.println(val);  
  analogWrite(3,val);
radio.write(val);

 

mag155
Offline
Зарегистрирован: 21.12.2017

Я и пытаюсь с ардуинки сделать драйвер чтоб можно было подключать любой индикатор. И к моему восторгу это таки получилось. Сейчас просто передаю значение с другой ардуины потенциометра но что то голова совсем зависла передает только от 0до 250 а надо от 0 до 1023??? Пойду наверно кофе бахну.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

mag155 пишет:

Получилось вот так 

void loop() {
  

 
if (radio.available()) {
while (radio.available()) {
  val = radio.read();
} 
   float numbers[] = {val}; 
      Serial.println(val);
  
 unsigned long currentMillis = millis();
   
 if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
   
  getDigits(numbers[numindex]);
    numindex += 1;
 
    if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
  }
 
  displayMessage(arr);

}
}

 

фигня получилась - скобки расставьте правильно, а то получается что отображение на дисплей происходит с периодом interval только в том случае если по SErial вам что то придет иначе ничего не отображается

нарисуте на бумаге (или в голове мысленно) что должно происходить

1. т.е. каждые полсекунды чтение датчика

2. при каждом loop отображение значения датчика

3. при приеме байта (слова) из Serial выводить в монитор число и что то делать

и все это должно работать независимо друг от друга

а щас у вас каша и в голове и в коде

mag155
Offline
Зарегистрирован: 21.12.2017
}

   float numbers[] = {val}; 
      Serial.println(val);

 unsigned long currentMillis = millis();
   
 if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;

  getDigits(numbers[numindex]);
    numindex += 1;
 }

    if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
 

Так кажись лучше отображается когда что-то пришло и без периода интерва

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

mag155 пишет:

}

   float numbers[] = {val}; 
      Serial.println(val);

 unsigned long currentMillis = millis();
   
 if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;

  getDigits(numbers[numindex]);
    numindex += 1;
 }

    if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
 

Так кажись лучше отображается когда что-то пришло и без периода интерва

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

mag155
Offline
Зарегистрирован: 21.12.2017

Пардон

 

mag155
Offline
Зарегистрирован: 21.12.2017

void loop() {
  

 
if (radio.available()) {
while (radio.available()) {
  val = radio.read();
}

   float numbers[] = {val}; 
      Serial.println(val);

 unsigned long currentMillis = millis();
   
 if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;

  getDigits(numbers[numindex]);
    numindex += 1;
 }

    if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
 
 
  displayMessage(arr);
}

}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

и чем последний код отличается от кода в сообщении 252?

ЗЫ. Вы мне напоминаете одного программиста из одной очень известной компании России,

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

он частенько тупо менял названия переменных, и типа исправил :)

естественно ошибка так и осталась.

mag155
Offline
Зарегистрирован: 21.12.2017

То что индикатор работает только если пришли данные мне подходит . Но я не пойму где вы видите что он моргает с периодом интервал ??? Подскажите  а то реально не пойму где?

void loop() {
  

 
if (radio.available()) {
while (radio.available()) {
  val = radio.read();
}

   float numbers[] = {val}; 
      Serial.println(val);

 unsigned long currentMillis = millis();
   
 if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;

  getDigits(numbers[numindex]);
    numindex += 1;
 
 }
    if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
 

  displayMessage(arr);
}

}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

вот так попробуйте

void loop() {
  
 unsigned long currentMillis = millis();

 
if (radio.available()) {
while (radio.available()) {
  val = radio.read();
}

   float numbers[] = {val}; 
      Serial.println(val);
}

   
 if((currentMillis - previousMillis) > interval) {
previousMillis = currentMillis;

  getDigits(numbers[numindex]);
    numindex += 1;
    if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
 
 }
 

  displayMessage(arr);

}

 

mag155
Offline
Зарегистрирован: 21.12.2017

В порту данные есть а на индикаторе Err .??

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

mag155 пишет:

В порту данные есть а на индикаторе Err .??

ниче не понял в чем вопрос

mag155
Offline
Зарегистрирован: 21.12.2017

В порту цифры 66 на индикаторе Err а должно быть тоже 66 ?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

вот смотрите:

приходят данные , переводятся в переменную val, выводяться в монитор,

далее каждые interval времени процедура getDigits формирует строку символов для вывода на экран - правильно?

возникает вопрос: а эта процедура которая формирует строку - она использует переменную val с исходными данными?

 

mag155
Offline
Зарегистрирован: 21.12.2017

Получается что нет.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

mag155 пишет:

Получается что нет.

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

mag155
Offline
Зарегистрирован: 21.12.2017

Ок. 

mag155
Offline
Зарегистрирован: 21.12.2017

Здялал так 

void loop() {
  unsigned long currentMillis = millis();
if (radio.available()) {
while (radio.available()) {
  val = radio.read();
}
 
  
     // Serial.println(val);
}  float numbers[] = {val};

  if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;

  getDigits(numbers[numindex]);
    numindex += 1;
  
       if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
  
}
  displayMessage(arr);

}

 

mag155
Offline
Зарегистрирован: 21.12.2017

И видимость переменной

int val=radio.read(); 

 

mag155
Offline
Зарегистрирован: 21.12.2017

Пкретикуйте если не сложно ??

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Работает? Устраивает? Значит нефиг ломать работающее.

mag155
Offline
Зарегистрирован: 21.12.2017

Работает устраивает. Но чё то точку не отображает?

mag155
Offline
Зарегистрирован: 21.12.2017
void loop() {
  unsigned long currentMillis = millis();
if (radio.available()) {
while (radio.available()) {
  val = radio.read();
}
//val = map(val, 0, 500, 1, 500);
  val = constrain(val, 0, 500);
  
      Serial.println(val);
}  float numbers[] = {val};

  if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;

  getDigits(numbers[numindex]);
    numindex += 1;
  
       if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
  
  }
  displayMessage(arr);

}

void getDigits (float value) {
  Serial.println("");

  // Выдаем ошибку на те значения, которые не можем показать
  if ((value >= 10000) ||
      (value <= -1000) ||
      (value > -0.01 && value < 0.001)) {
    for (int i = 0; i < 4; i++) { // Каждый разряд по очереди
      for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты
        arr[i][k] = err[i][k];
      }
    }
    return; // Выходим
  }
  int digits = 4; // У нас 4 разряда
  if (value < 0) digits = 3; // Из-за минуса один символ убирается*/
  // Делим число на 2 группы - отдельно целую часть и дробную.
  int intPart = (int)abs(value);
  int intLength = ((String)intPart).length(); // Смотрим, сколько разрядов занимает целая часть
  // На дробную часть у нас остается разрядов: digits-intLength
  int fracPart = (int)((abs(value) - abs(intPart)) * 1000); // Мы можем показать максимум 3 знака после запятой - 0,000
  int fracDigits = digits - intLength;
  fracPart = (((String)fracPart).substring(0, fracDigits)).toInt();
  // Собираем строку для отображения
  String output = (value < 0) ? "-"  : "";
  output += (String)intPart;
  String outputFrac = ((digits - intLength <= 0) || (fracPart == 0)) ? "" : ((String)"." + ((String)fracPart).substring(0, digits - intLength));
  output += (String)outputFrac;
   // Дополняем символы спереди, если цифр слишком мало, например для "-1" делаем "  -1"
  String spaces = "     ";
  digits = 4;
  if (~output.indexOf(".")) digits += 1;
  if (output.length() < digits) output = spaces.substring(0, digits - output.length()) + output;
  // Формирум данные для показа:
  int dig = -1;
  for (int i = 0; i < output.length(); i++) {
    String _char = output.substring(i, i + 1);
    if (_char != ".") dig += 1; // Точка не занимает сегмент - увеличиваем на 1
    int actualdigit = 11; // По умолчанию пустой символ
    if ((_char == "-")) {
      actualdigit = 10;
    }
    else if (_char == " " || _char == ".") {
    }
    else {
      actualdigit = _char.toInt();
    }
    if (_char == ".") {
      arr[dig][7] = 1; // Если нужно - ставим точку
    }
    else  {
      for (int n = 0; n <= 7; n++) {
        arr[dig][n] = seg[actualdigit][n];
      }
    }
  }
}
void displayMessage(int dig[4][8]) {
  for (int i = 0; i < 4; i++) { // Каждый разряд по очереди
   for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты
   digitalWrite(segmentsPins[k], ((dig[i][k] == 1) ? 1 : 0));
 }
digitalWrite(anodPins[i], 0);
delay(2);
digitalWrite(anodPins[i], 1);
  
  }
  }

 

mag155
Offline
Зарегистрирован: 21.12.2017

Даже если вот так пишу показует только 9

float numbers[] = {9.3};

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

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

mag155
Offline
Зарегистрирован: 21.12.2017

А разве 45 и 46 строки не для этого ?

mag155
Offline
Зарегистрирован: 21.12.2017

Или все дело в 63 строке?

mag155
Offline
Зарегистрирован: 21.12.2017

И 73 с 74 ?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Вроде они, но как видите не работает)
Разбираться надо - некогда

mag155
Offline
Зарегистрирован: 21.12.2017

ПРОБЛЕМА ОКАЗАЛАСЬ В БИБЛИОТЕКЕ 

#include <SoftwareSerial.h>

 

mag155
Offline
Зарегистрирован: 21.12.2017

Доброго времени суток решил добить тему с индикатором. Вопрос как допилить код чтоб работатл со здвиговыми регистрами как например в 174 сообщении ???

arduino_kz
Offline
Зарегистрирован: 25.08.2016

Доброго времени суток.

В начале темы автор сделал схему подключения скетч для индикатора с общим анода. Что можно сделать если индикатор с общим катодом? без транзисторов не обойтись?

mag155
Offline
Зарегистрирован: 21.12.2017

Нужно управлять минусом тоест low.

arduino_kz
Offline
Зарегистрирован: 25.08.2016

Делаю все по схеме так же?

по части скетча где нужно поменять?

Буду благодарен за совет?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

А нужны ли эти заморочки когда есть дешевая микросхема TM1650, а также TM1637 TM1638

 

 

CheBuraw
Offline
Зарегистрирован: 10.02.2015

arduino_kz пишет:

Делаю все по схеме так же?
по части скетча где нужно поменять?
Буду благодарен за совет?

Вам нужно поправить только в этом месте:

// Настройка комбинации для отображения каждого номера на дисплее.
// Комбинация выбрана на основе таблицы отображаемого знака данным порта
// Соответственно { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , dp, - }
byte g_digits[12]={192,249,164,176,153,146,130,248,128,144,127,255}; //массив цифр, генерирующий из сегментов цифры
byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды

А рассчитать можно по аналогии с табличкой:

Соответствие отображаемого знака данным порта
общий анод
__________________________________________________
     |   двоичный вид по сегментам   |            |
Цифра|dp | G | F | E | D | C | B | A | Десятичный |
-----|---|---|---|---|---|---|---|---|------------|
  0  | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |    192     |
  1  | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |    249     |
  2  | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 |    164     |
  3  | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |    176     |
  4  | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |    153     |
  5  | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |    146     |
  6  | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |    130     |
  7  | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |    248     |
  8  | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |    128     |
  9  | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |    144     |
 dp  | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |    127     |
-----*---*---*---*---*---*---*---*---*------------*

Только у вас там где 1 должен быть 0. К примеру цифра "0" при общем аноде имеет
бинарный вид: 11000000 = 192 в десятичном виде, при общем катоде:
бинарный вид: 00111111 = 63 в десятичном виде, и так далее для остальных символов.

При этом не забудте поправить и массив для разрядов. там так же нужно пересчитать по тому же принципу:
общий анод, первый разряд 00000001 = 1
общий катод, 11111110 = 254
а можно еще проще для разрядов - имеющийся адрес вычитать из 255:
255-1=254, 255-2=253, 255-4=251, 255-8=247 и тогда для разрядов адреса будут такие:
 

byte g_registerArray[4]={254,253,251,247}; //массив цифр, указывающий разряды

Если лень вспоминать школьный курс информатики ;)

jeka_tm пишет:

А нужны ли эти заморочки когда есть дешевая микросхема TM1650, а также TM1637 TM1638

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

CheBuraw пишет:

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

Да я тоже самое делал. Просто сейчас если и ставить только расширения выходных портов, для семисегментного уже пожалуй нет

arduino_kz
Offline
Зарегистрирован: 25.08.2016

Получилось спасибо большое!