roboforum.ru

Технический форум по робототехнике.

Arduino и 7 сегментный индикатор

Как собрать и запрограммировать робота на Arduino(Freeduino, Roboduino, Seeduino ...). Используем Wiring и Processing.

Arduino и 7 сегментный индикатор

Сообщение aspire89 » 01 апр 2010, 22:09

Приветствую всех пользователей форума.
На днях приобрел Freeduino 2009 - полный аналог Arduino Duemilanove.
Дома нашел плату с 7 сегментными индикаторами и цифровой датчик температуры DS1820.
Сначала попробовал по отдельности индикатор и датчик, все работает, потом решил объединить 2 задачи и выводить значение температуры на индикатор.
Написал следующий код:
Код: Выделить всёРазвернуть
#include <OneWire.h>
#include <OneWireTempSensor.h>
#include <MsTimer2.h>

OneWireTempSensor sensors(12);       // the OneWireTempSensor object
int   numdevs;                       // number of devices

int pin1 = 6;
int pin2 = 5;                                    //                            --6--
int pin3 = 8;                                    //                         5 |     | 7
int pin4 = 4;                                    //                           |--4--|
int pin5 = 2;                                    //                         1 |     | 3
int pin6 = 7;                                    //                            --2--
int pin7 = 3;
int gnd1 = 11;                                   //                          gnd1 is display 1's gnd
int gnd2 = 10;                                   //                          gnd2 is display 2's gnd
int timer1 = 100;                                //   A timer, to run the for loop 100 times, which turns out as 1 second.
                                   
int var1 = 0;
int var2 = 0;


void setup(){ 
  numdevs = sensors.getDevices();    // this searches for all DS1820 devices on the OneWire bus
 
  pinMode(pin1, OUTPUT);
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);           //The following sets up all of the pins for use.
  pinMode(pin5, OUTPUT);
  pinMode(pin6, OUTPUT);
  pinMode(pin7, OUTPUT);
  pinMode(gnd1, OUTPUT);
  pinMode(gnd2, OUTPUT);
 
  ds1820();
 
  MsTimer2::set(3000, ds1820); // 3000ms период
  MsTimer2::start();  //включить таймер
}

void ds1820(){ 
  int currdev;
  float real_temp;
  int   temp;

  // loop through all the DS1820 temp sensors on the bus
  for (currdev = 0; currdev < numdevs; ++currdev) {
    /* get the temperature */
    real_temp = sensors.getTempC(currdev);
    temp = (int) real_temp;
    var2 = temp / 10;
    var1 = temp - pow((temp/10), 1)*10;
  }
}

void loop() {
switch (var1) {
    case 0:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B1);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B0);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
        }
      break;
    case 1:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B0);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B0);
        digitalWrite(pin5, B0);
        digitalWrite(pin6, B0);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
       }
      break;
    case 2:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B1);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B0);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B0);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
        }
      break;
    case 3:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B0);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
       }
      break;
    case 4:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B0);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B0);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
       }
      break;
    case 5:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B0);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
       }
      break;
    case 6:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B1);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B0);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
       }
      break;
    case 7:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B0);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B0);
        digitalWrite(pin5, B0);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
       }
      break;
    case 8:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B1);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
       }
      break;
     case 9:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B0);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B1);
        digitalWrite(gnd2, B0);
       }
      break;
}   

   switch (var2) {
    case 0:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B1);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B0);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
        }
      break;
    case 1:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B0);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B0);
        digitalWrite(pin5, B0);
        digitalWrite(pin6, B0);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
       }
      break;
    case 2:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B1);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B0);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B0);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
        }
      break;
    case 3:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B0);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
       }
      break;
    case 4:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B0);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B0);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
       }
      break;
    case 5:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B0);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
       }
      break;
    case 6:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B1);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B0);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
       }
      break;
    case 7:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B0);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B0);
        digitalWrite(pin5, B0);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
       }
      break;
    case 8:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B1);
        digitalWrite(pin2, B1);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
       }
      break;
     case 9:
      for (int i=0; i<timer1; i++){
        digitalWrite(pin1, B0);
        digitalWrite(pin2, B0);
        digitalWrite(pin3, B1);
        digitalWrite(pin4, B1);
        digitalWrite(pin5, B1);
        digitalWrite(pin6, B1);
        digitalWrite(pin7, B1);
        digitalWrite(gnd1, B0);
        digitalWrite(gnd2, B1);
       }
      break;
}
}

Все бы хорошо, но при срабатывании события таймера, либо первая, либо вторая цифра на индикаторе пропадает на время выполнения процедуры ds1820. Чем реже сделать период таймера, тем это будет менее заметно. Хочется найти решение этой проблемы. Подскажите, пожалуйста, может я чего неправильно делаю.
Записал видео того мерцания, как выгрузится, так выложу сюда.
Аватара пользователя
aspire89
 
Сообщения: 6
Зарегистрирован: 01 апр 2010, 20:34
Откуда: Пермь
прог. языки: Visual Basic, Delphi, Python

Re: Arduino и 7 сегментный индикатор

Сообщение avr123.nm.ru » 01 апр 2010, 23:21

Это и есть призрачность простоты Arduino. Чтобы сделать что-то нормальное ВСЕРАВНО надо изучать и программирование и как МК устроен.

Надо работать с 1-wire в прерываниях чтоб не останавливать динамику индикации.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Arduino и 7 сегментный индикатор

Сообщение tsrodger » 02 апр 2010, 00:37

Тут итак на прерывания по таймеру... Просто прерывания - это как раз одно из проблемных мест :(
не скажу в чем тут точно проблема (схему бы увидеть), но мне кажется вам стоит еще раз посмотреть в сторону управление сигналами GND1 и GND2 (раз гашение происходит сегментами).
Аватара пользователя
tsrodger
 
Сообщения: 134
Зарегистрирован: 18 сен 2008, 17:31
Skype: tsrodger
прог. языки: VB.Net, C, PHP

Re: Arduino и 7 сегментный индикатор

Сообщение aspire89 » 02 апр 2010, 09:39

Нарисовал схему:
Изображение

И видео: http://vimeo.com
Аватара пользователя
aspire89
 
Сообщения: 6
Зарегистрирован: 01 апр 2010, 20:34
Откуда: Пермь
прог. языки: Visual Basic, Delphi, Python

Re: Arduino и 7 сегментный индикатор

Сообщение rig » 02 апр 2010, 10:14

если пользовать стандартную функцию то так и будет.
время измерения 0,5 сек примерно, на эти 0,5 сек все останавливается.
Если работать напрямую с датчиком, можно подать команду на имерение температуры и пока идет измерение продолжить вывод индикации.
Аватара пользователя
rig
 
Сообщения: 1437
Зарегистрирован: 03 авг 2007, 19:43
Откуда: Екатеринбург
прог. языки: Си, асм со словарем

Re: Arduino и 7 сегментный индикатор

Сообщение rig » 02 апр 2010, 10:35

удобный/красивый вывод на 7сигментрный индикатор
верхушка айсберга :wink: :
Код: Выделить всёРазвернуть
#include <Hardware.h>
#include <7seg.h>

unsigned char IndTabHex[]={SIGN_0,SIGN_1,SIGN_2,SIGN_3,SIGN_4,SIGN_5,SIGN_6,SIGN_7,SIGN_8,SIGN_9};


в тексте программы для вывода числа от 0 до 9 будет выглядеть так:

Код: Выделить всёРазвернуть
out_zn1=IndTabHex[0];
out_zn1=IndTabHex[1];
и тд.
out_zn1=IndTabHex[9];
// можно и так
out_zn1=SIGN_0;
out_zn1=SIGN_1;
...
out_zn1=SIGN_9;


вывод числа 23 к примеру так:
Код: Выделить всёРазвернуть
unsigned char tmp=23;
out_zn1=IndTabHex[tmp/10];
out_zn2=IndTabHex[tmp%10];


айсберг изнутри:
<7seg.h> Тут все мои комбинации на данный момент, какието понятны срзу какието можно на индикаторе сначала представить(чтоб зажечь сегмент нужно выставить 0, если надо выставить 1 убрать инверсию ~):
Код: Выделить всёРазвернуть
#define SIGN_ZAP   ~(1<<SEG_H)
#define SIGN_0      ~((1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_F))
#define SIGN_1      ~((1<<SEG_B)|(1<<SEG_C))
#define SIGN_2      ~((1<<SEG_A)|(1<<SEG_B)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_G))
#define SIGN_3      ~((1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(1<<SEG_G))
#define SIGN_4      ~((1<<SEG_B)|(1<<SEG_C)|(1<<SEG_F)|(1<<SEG_G))
#define SIGN_5      ~((1<<SEG_A)|(1<<SEG_F)|(1<<SEG_G)|(1<<SEG_C)|(1<<SEG_D))
#define SIGN_6      ~((1<<SEG_A)|(1<<SEG_F)|(1<<SEG_G)|(1<<SEG_C)|(1<<SEG_D)|(1<<SEG_E))
#define SIGN_7      ~((1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C))
#define SIGN_8      ~((1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_F)|(1<<SEG_G))
#define SIGN_9      ~((1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(1<<SEG_F)|(1<<SEG_G))
#define SIGN_A      ~((1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(1<<SEG_G)|(1<<SEG_E)|(1<<SEG_F))
#define SIGN_B      ~((1<<SEG_C)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_F)|(1<<SEG_G))
#define SIGN_C      ~((1<<SEG_A)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_F))
#define SIGN_D      ~((1<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_G))
#define SIGN_E      ~((1<<SEG_A)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_F)|(1<<SEG_G))
#define SIGN_F      ~((1<<SEG_A)|(1<<SEG_E)|(1<<SEG_F)|(1<<SEG_G))
#define SIGN_P      ~((1<<SEG_A)|(1<<SEG_B)|(1<<SEG_E)|(1<<SEG_F)|(1<<SEG_G))
#define SIGN_Tc      ~((1<<SEG_A)|(1<<SEG_B)|(1<<SEG_F)|(1<<SEG_G))
#define SIGN_t      ~((1<<SEG_D)|(1<<SEG_E)|(1<<SEG_F)|(1<<SEG_G))
#define SIGN_MAX   ~((1<<SEG_A)|(1<<SEG_B))
#define SIGN_MIN   ~((1<<SEG_D)|(1<<SEG_E))

#define SIGN_MINUS   ~(1<<SEG_G)
#define SIGN_SPACE   0xFF      // Смотри таблицу ITab

#define SIGN_L      ~((1<<SEG_F)|(1<<SEG_E)|(1<<SEG_D))
#define SIGN_H      ~((1<<SEG_F)|(1<<SEG_E)|(1<<SEG_G)|(1<<SEG_B)|(1<<SEG_C))


<Hardware.h> Соответствие сегмента ножке порта.
Код: Выделить всёРазвернуть
/*для индикации*/
#define SEG_A   7
#define SEG_B   6
#define SEG_C   4
#define SEG_D   2
#define SEG_E   1
#define SEG_F   0
#define SEG_G   5
#define SEG_H   3
Аватара пользователя
rig
 
Сообщения: 1437
Зарегистрирован: 03 авг 2007, 19:43
Откуда: Екатеринбург
прог. языки: Си, асм со словарем

Re: Arduino и 7 сегментный индикатор

Сообщение aspire89 » 02 апр 2010, 22:23

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

rig, спасибо за примеры с индикатором.
Аватара пользователя
aspire89
 
Сообщения: 6
Зарегистрирован: 01 апр 2010, 20:34
Откуда: Пермь
прог. языки: Visual Basic, Delphi, Python

Re: Arduino и 7 сегментный индикатор

Сообщение aspire89 » 04 апр 2010, 22:15

Нашел пример пользователя vvvictor, как раз такой какой и искал:
Код: Выделить всёРазвернуть
#include <avr/interrupt.h>
#include <DallasTemperature.h>

int rdigs[] = {9, 10, 11, 12};
int rsegs[] = { 1, 2, 3, 4, 5, 6, 7, 8};
bool digits[15][8] = {
  {1, 1, 1, 1, 1, 1, 0, 0},  //0
  {0, 1, 1, 0, 0, 0, 0, 0},  //1
  {1, 1, 0, 1, 1, 0, 1, 0},  //2
  {1, 1, 1, 1, 0, 0, 1, 0},  //3
  {0, 1, 1, 0, 0, 1, 1, 0},  //4
  {1, 0, 1, 1, 0, 1, 1, 0},  //5
  {1, 0, 1, 1, 1, 1, 1, 0},  //6
  {1, 1, 1, 0, 0, 0, 0, 0},  //7
  {1, 1, 1, 1, 1, 1, 1, 0},  //8
  {1, 1, 1, 1, 0, 1, 1, 0},  //9
  {0, 0, 0, 0, 0, 0, 0, 0},  //none
  {0, 0, 0, 0, 0, 0, 1, 0},  //-
  {1, 0, 0, 1, 1, 1, 1, 1},  //E.
  {0, 0, 0, 0, 1, 0, 1, 1},  //r.
  {1, 1, 1, 1, 1, 1, 0, 1}   //0.
};
int cdigit = 0;
int odigit = 0;
int displ[] = {0, 8, 4, 9};

DallasTemperature tempSensor;

void displayTemperature(float term);
void cleardisplay();
void displayErr(int err);


// Подпрограмма прерывания
ISR(TIMER2_OVF_vect) {
//  return;
  int dig;
  if(cdigit < 0 || cdigit > 3) cdigit = 0;
  digitalWrite(rdigs[odigit], LOW);
  dig = abs(displ[cdigit]);
  if(displ[cdigit] < 0) digits[dig][7] = 1;
  else digits[dig][7] = 0;
  for(int i = 0; i < 8; i++) digitalWrite(rsegs[i], !(digits[dig][i]));
  digitalWrite(rdigs[cdigit], HIGH);
  odigit = cdigit;
  cdigit++;
  TCNT2 = 0;
}

void setup() {
  for(int i = 0; i<4; i++) {
    pinMode(rdigs[i], OUTPUT);
    digitalWrite(rdigs[i], LOW);
  }
  for(int i = 0; i<8; i++) {
    pinMode(rsegs[i], OUTPUT);
    digitalWrite(rsegs[i], LOW);
  }
  //Установка делителей таймера
  TCCR2A = 0;
  TCCR2B |= 1<<CS22;
  TCCR2B &= ~((1<<CS21) | (0<<CS20));
  TCCR2B &= ~((1<<WGM21) | (1<<WGM20));
  //Timer2 Overflow Interrupt Enable 
  TIMSK2 |= 1<<TOIE2;
  //reset timer
  TCNT2 = 0;
  cleardisplay();
  tempSensor.begin(0);
}

void loop() {
  byte i;
  byte present = 0;
  byte addr[8];

  switch(tempSensor.isValid()) {
        case 1:
            //Invalid CRC
            displayErr(-1);
            tempSensor.reset(); // Attempts to redetect IC
            return;
        case 2:
            //Not a valid device
            displayErr(-2);
            tempSensor.reset(); // Attempts to redetect IC
            return;
  }
  displayTemperature(tempSensor.getTemperature());
}

void displayTemperature(float term) {
  int bdis[4] = {10, 10, 10, 10};
  int cycle;
  int temp = 100*abs(term);

  cycle = 2;
  while(temp > 0) {
    for(int i=0; i<3; i++) bdis[i] = bdis[i+1];
    bdis[3] = temp % 10;
    if(cycle==0) {
      if(bdis[3]==0) bdis[3] = -14;
      else bdis[3] *= -1;
    }
    temp /= 10;
    cycle--;
  }
  if(term<0) {
    for(int i=0; i<3; i++) bdis[i] = bdis[i+1];
    bdis[3] = 11;
    if(cycle==0) bdis[3] *= -1;
  }
  for(int i=0; i<4; i++) displ[i] = bdis[i];
}


void cleardisplay() {
  for(int i=0; i<4; i++) displ[i] = 10;
}

void displayErr(int err) {
  displ[0] = err;
  displ[1] = -13;
  displ[2] = -13;
  displ[3] = -12;
}

Только при компилировании появляются ошибки:
Код: Выделить всёРазвернуть
ошибка: нет подходящей функции для вызова ‘DallasTemperature::DallasTemperature()’/usr/share/arduino/libraries/DallasTemperature/DallasTemperature.h:62: замечание: претенденты: DallasTemperature::DallasTemperature(OneWire*)

/usr/share/arduino/libraries/DallasTemperature/DallasTemperature.h:59: замечание:              DallasTemperature::DallasTemperature(const DallasTemperature&)

In function ‘void setup()’:
In function ‘void loop()’:

Библиотеку DallasTemperature.h установил и проверил, а в этом примере ошибка почему то.
Еще нигде ничего не нашел про библиотеку avr/interrupt.h
Её нужно отдельно устанавливать или она уже предустановлена?
Аватара пользователя
aspire89
 
Сообщения: 6
Зарегистрирован: 01 апр 2010, 20:34
Откуда: Пермь
прог. языки: Visual Basic, Delphi, Python

Re: Arduino и 7 сегментный индикатор

Сообщение aspire89 » 06 апр 2010, 15:17

Связался с автором приведенного выше кода и он в кратчайшие сроки доработал код. Теперь будет работать на индикаторах с общим анодом и катодом.
Код: Выделить всёРазвернуть
#include <avr/interrupt.h>
#include <DallasTemperature.h>

//Снять комментарий для индикаторов с общим катодом
//#define OKAT

bool LLOW = LOW;
bool HHIGH = HIGH;

int rdigs[] = {9, 10, 11, 12};
int rsegs[] = { 1, 2, 3, 4, 5, 6, 7, 8};
bool digits[15][8] = {
  {1, 1, 1, 1, 1, 1, 0, 0},  //0
  {0, 1, 1, 0, 0, 0, 0, 0},  //1
  {1, 1, 0, 1, 1, 0, 1, 0},  //2
  {1, 1, 1, 1, 0, 0, 1, 0},  //3
  {0, 1, 1, 0, 0, 1, 1, 0},  //4
  {1, 0, 1, 1, 0, 1, 1, 0},  //5
  {1, 0, 1, 1, 1, 1, 1, 0},  //6
  {1, 1, 1, 0, 0, 0, 0, 0},  //7
  {1, 1, 1, 1, 1, 1, 1, 0},  //8
  {1, 1, 1, 1, 0, 1, 1, 0},  //9
  {0, 0, 0, 0, 0, 0, 0, 0},  //none
  {0, 0, 0, 0, 0, 0, 1, 0},  //-
  {1, 0, 0, 1, 1, 1, 1, 1},  //E.
  {0, 0, 0, 0, 1, 0, 1, 1},  //r.
  {1, 1, 1, 1, 1, 1, 0, 1}   //0.
};
int cdigit = 0;
int odigit = 0;
int displ[] = {0, 8, 4, 9};

DallasTemperature tempSensor;

void displayTemperature(float term);
void cleardisplay();
void displayErr(int err);


// Подпрограмма прерывания
ISR(TIMER2_OVF_vect) {
//  return;
  int dig;
  if(cdigit < 0 || cdigit > 3) cdigit = 0;
  digitalWrite(rdigs[odigit], LLOW);
  dig = abs(displ[cdigit]);
#ifdef OKAT
  if(displ[cdigit] < 0) digits[dig][7] = 0;
  else digits[dig][7] = 1;
#else 
  if(displ[cdigit] < 0) digits[dig][7] = 1;
  else digits[dig][7] = 0;
#endif
  for(int i = 0; i < 8; i++) digitalWrite(rsegs[i], !(digits[dig][i]));
  digitalWrite(rdigs[cdigit], HHIGH);
  odigit = cdigit;
  cdigit++;
  TCNT2 = 0;
}

void setup() {
  int i;
#ifdef OKAT
  int j;
  LLOW = HIGH;
  HHIGH = LOW;
  for(i=0; i<15; i++) {
   for(j=0; j<8; j++) {
     if(digits[i][j]==0) digits[i][j]=1;
     else digits[i][j]=0;
   }
  }
#endif
  for(i=0; i<4; i++) {
    pinMode(rdigs[i], OUTPUT);
    digitalWrite(rdigs[i], LLOW);
  }
  for(i=0; i<8; i++) {
    pinMode(rsegs[i], OUTPUT);
    digitalWrite(rsegs[i], LLOW);
  }
  //Установка делителей таймера
  TCCR2A = 0;
  TCCR2B |= 1<<CS22;
  TCCR2B &= ~((1<<CS21) | (0<<CS20));
  TCCR2B &= ~((1<<WGM21) | (1<<WGM20));
  //Timer2 Overflow Interrupt Enable 
  TIMSK2 |= 1<<TOIE2;
  //reset timer
  TCNT2 = 0;
  cleardisplay();
  tempSensor.begin(0);
}

void loop() {
  byte i;
  byte present = 0;
  byte addr[8];

  switch(tempSensor.isValid()) {
        case 1:
            //Invalid CRC
            displayErr(-1);
            tempSensor.reset(); // Attempts to redetect IC
            return;
        case 2:
            //Not a valid device
            displayErr(-2);
            tempSensor.reset(); // Attempts to redetect IC
            return;
  }
  displayTemperature(tempSensor.getTemperature());
}

void displayTemperature(float term) {
  int bdis[4] = {10, 10, 10, 10};
  int cycle;
  int temp = 100*abs(term);

  cycle = 2;
  while(temp > 0) {
    for(int i=0; i<3; i++) bdis[i] = bdis[i+1];
    bdis[3] = temp % 10;
    if(cycle==0) {
      if(bdis[3]==0) bdis[3] = -14;
      else bdis[3] *= -1;
    }
    temp /= 10;
    cycle--;
  }
  if(term<0) {
    for(int i=0; i<3; i++) bdis[i] = bdis[i+1];
    bdis[3] = 11;
    if(cycle==0) bdis[3] *= -1;
  }
  for(int i=0; i<4; i++) displ[i] = bdis[i];
}

void cleardisplay() {
  for(int i=0; i<4; i++) displ[i] = 10;
}

void displayErr(int err) {
  displ[0] = err;
  displ[1] = -13;
  displ[2] = -13;
  displ[3] = -12;
}

Если будут вопросы, пишите.
Аватара пользователя
aspire89
 
Сообщения: 6
Зарегистрирован: 01 апр 2010, 20:34
Откуда: Пермь
прог. языки: Visual Basic, Delphi, Python

Re: Arduino и 7 сегментный индикатор

Сообщение kazakoff64 » 13 авг 2013, 00:02

Решил попробовать сделать тоже самое, взял исходник выше, при компиляции ошибки.
Код: Выделить всёРазвернуть
sketch_aug12a.cpp:42:19: error: no matching function for call to ‘DallasTemperature::DallasTemperature()’
/usr/share/arduino/libraries/temperature_control/DallasTemperature.h:67:3: note: candidates are: DallasTemperature::DallasTemperature(OneWire*)
/usr/share/arduino/libraries/temperature_control/DallasTemperature.h:64:1: note:                 DallasTemperature::DallasTemperature(const DallasTemperature&)
sketch_aug12a.cpp: In function ‘void setup()’:
sketch_aug12a.cpp:101:21: error: no matching function for call to ‘DallasTemperature::begin(int)’
/usr/share/arduino/libraries/temperature_control/DallasTemperature.h:70:8: note: candidate is: void DallasTemperature::begin()
sketch_aug12a.cpp: In function ‘void loop()’:
sketch_aug12a.cpp:109:21: error: ‘class DallasTemperature’ has no member named ‘isValid’
sketch_aug12a.cpp:113:24: error: ‘class DallasTemperature’ has no member named ‘reset’
sketch_aug12a.cpp:118:24: error: ‘class DallasTemperature’ has no member named ‘reset’
sketch_aug12a.cpp:121:33: error: ‘class DallasTemperature’ has no member named ‘getTemperature’
kazakoff64
 
Сообщения: 1
Зарегистрирован: 12 авг 2013, 23:57

Re: Arduino и 7 сегментный индикатор

Сообщение aspire89 » 14 авг 2013, 20:26

kazakoff64 писал(а):Решил попробовать сделать тоже самое, взял исходник выше, при компиляции ошибки.

Я догадываюсь что версия у вас 1.5.х, попробуйте на 1.0.х
Аватара пользователя
aspire89
 
Сообщения: 6
Зарегистрирован: 01 апр 2010, 20:34
Откуда: Пермь
прог. языки: Visual Basic, Delphi, Python

Re: Arduino и 7 сегментный индикатор

Сообщение Angel71 » 14 авг 2013, 21:42

aspire89, для индикаторов есть спец микры, к примеру max7219
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1

Re: Arduino и 7 сегментный индикатор

Сообщение justMike » 15 дек 2014, 17:39

Всем привет! Тоже столкнулся с проблемой мерцания 7-сегментного дисплея при опросе датчика температуры. Столкнулся с теми же проблемами при компиляции вышеизложенного кода. Версия IDE 1.0.5
justMike
 
Сообщения: 1
Зарегистрирован: 15 дек 2014, 17:35

Re: Arduino и 7 сегментный индикатор

Сообщение Nemo31 » 15 мар 2015, 01:30

Добрый день!
Я новичек, и с первых же шагов столкнулся с непонятной проблемой мерцания индикатора при опросе датчика температуры.
С чужими кодами очень трудно разбираться. Крайне непонятно. Писал свой. Все измеряется и выводиться на индикатор, но мерцает. Индикатор использую - готовый шилд из Китая на основе 2х 74hc595, Arduino UNO R3, датчик ds18b20 - задействованы все 3 ноги.

Код: Выделить всёРазвернуть
#include <OneWire.h>

// Диапазон отражения температурных значений на индикаторе max = 327.67 min = 99.99
 
byte latchPin = 8;     // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
byte clockPin = 12;    // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
byte dataPin = 11;     // Пин "данных" подключен к QH (SDI, DS) входу 74HC595

// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[25]={
  B11000000, B11111001, B10100100, B10110000, B10011001,   // 0 1 2 3 4
  B10010010, B10000010, B11111000, B10000000, B10010000,   // 5 6 7 8 9
  B01000000, B01111001, B00100100, B00110000, B00011001,   // 0. 1. 2. 3. 4.
  B00010010, B00000010, B01111000, B00000000, B00010000,   // 5. 6. 7. 8. 9.
  B01111111, B10111111, B10011100, B11000110,   // точка, прочерк, градус, цельсия
  B11111111, };                              // все сегменты выключены
byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды

OneWire ds (10);    // Пин где подвешен ds18b20
byte data[12];
float celsius;      // Переменная для хранения измеренной температуры
int raw;
unsigned long time=0;
boolean flag=1;


void setup()
{ // обозначаем все пины как выходы
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop()
{
  if(flag)
  {
    DS_start();
    time=millis();
    flag=0;
  }
  if((millis()-time) > 750 && !flag)
  {
    DS_read();
    flag=1;
  }
   //а здесь постоянно выводим. температуру брать из celsius
  ledDigitDisplay(celsius); // Можете подставить любые значения.
  // Следите чтобы стояла именно "." (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
  // Диапазон отражения температурных значений на индикаторе max = 327.67 min = 99.99
  // max - потому что int-диапазон только до 32767
  // min - потому что в не думаю что где то меньше значение потребуется
}

void DS_start()
{
  ds.reset();
  ds.write(0xCC);
  ds.write(0x44); // начать преобразования, с паразитным питанием на в конце
}

void DS_read()
{
  ds.reset();
  ds.write(0xCC);
  ds.write(0xBE); // Чтение Scratchpad
  for (byte i = 0; i < 9; i++)
    { //  нам нужно 9 байт (с сотыми после запятой)
      data[i] = ds.read ();
    }
  raw =  (data[1] << 8) | data[0];  //  Пересчитываем в температуру
  celsius =  (float)raw / 16.0;
}

void ledDigitDisplay(float temperature)
  {
    int disp;                  // Переменная для целых чисел температуры               
    int floatingPoint = 0;     // Переменная "плавающая точка" для хранения номера регистра в котором стоит "."
    int index;
 
    disp = temperature * 100;   // Избавляемся от десятых и сотых (оставляем челую часть числа)
    if (disp < 0) disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
    if (disp > 9999) disp = int (disp / 10); // сдвиг до отображения только десятых в положительном диапазоне > 99.99
    if (temperature <= -10) disp = int (disp / 10); // сдвиг до отображения только десятых в отрицательных диапазонах < -10

    // Определяемся в каком именно разряде ставить точку
    if ((temperature <= -10 && temperature > -100) || (temperature > 100 && temperature < 1000))
        floatingPoint = 1;
    else
        if ((temperature < 0 && temperature > -10) || (temperature > 0 && temperature < 100))
            floatingPoint = 2;
        else floatingPoint = 4;

    if (temperature < -99.99 || temperature > 327.67)
      {
        // Обработаем выход за пределы min и max температур
        for (int i = 0; i < 4; i++)
            Indicate( i, 21 ); // Ставим во всех разрядах прочерки
      }
    else
      {
        if(temperature < 0) Indicate( 3, 21 );   // если значение минусовое то ставим минус в первом индикаторе
        if((disp / 100) < 1) Indicate( 2, 10 );
        if((disp / 10) < 1) Indicate( 1, 0 );
        if(temperature >= 0) index = 4;
          else index = 3;
       
        // Собственно, основной цыкл. Тут все и происходит
        for (int i = 0; i < index; i++)
            {
              if (i == 0 || disp != 0)
                  if (i == floatingPoint)
                      Indicate( i, (disp % 10) + 10 );
                  else
                      Indicate( i, disp % 10 );
              else
                Indicate( i, 24 );
              disp /= 10;
            }
      } 
  }

void Indicate(byte r, byte x) // Функция собственно, отображения цыфр на индикаторе.
  {
    byte TimeLight = 1;    // Время для разогрева сегментов - не более 2, иначе будет мерцание около-нулевых значений
    byte SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
    byte RazrDisplay=g_registerArray[r];  // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
    digitalWrite(latchPin, LOW);   // устанавливаем синхронизацию "защелки" на LOW
      shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay);  // Записываем информацию для первого регистра (Номер символа)
      shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
    digitalWrite(latchPin, HIGH);  //"защелкиваем" регистр, тем самым устанавливая значения на выходах

    delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
  }


Код старался расписывать с максимальными комментариями.
Подскажите пожалуйста как избавиться от мерцания?
Nemo31
 
Сообщения: 1
Зарегистрирован: 15 мар 2015, 01:09

Re: Arduino и 7 сегментный индикатор

Сообщение Romikgy » 16 мар 2015, 00:01

Подскажите пожалуйста как избавиться от мерцания?

увеличить частоту отображения
die Wahrheit ist irgendwo da draußen
Аватара пользователя
Romikgy
 
Сообщения: 750
Зарегистрирован: 15 ноя 2009, 13:37
Откуда: Porto Franco "Odessa"


Вернуться в Arduino и другие Xduino

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

cron