Arduino nano Proteus 8.3

serg-abeliar
Offline
Зарегистрирован: 21.07.2016

Написал проект, отладку проходит, но частота отображения очень мала. Т.к. это первое знакомство с Ардуиной вообще то требуется помощь.

 

serg-abeliar
Offline
Зарегистрирован: 21.07.2016

код

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
 
#include <Wire.h>
#include "RTClib.h"
#include <OneWire.h>
#include "EEPROM.h"
 
               //инициализация  
RTC_DS1307 rtc;
OneWire  ds(11);              // нога куда подключен Ds18B20
        
boolean started = false;      // булевая переменная "started" = ложь
int hour;                     //часы 
boolean count2I = 0;          // счетчик расхода
int count2P = 0;              // -//-
unsigned long InputD2P = 0UL; // -//-
int count3P = 0;              // -//-
int latchPin = 9;             //Пин подключен к ST_CP входу 74HC595
int clockPin = 10;            //Пин подключен к SH_CP входу 74HC595
int dataPin = 8;              //Пин подключен к DS входу 74HC595
int InputK = 7;               //номер нажатой кнопки (7-не нажато ничего)
boolean razr = 0;             //разрешение изменения параметра
int rash = 0;                 //переменаая корректировки уровня топлива
int rashod = 50;              // уровень топлива из памяти (5л)
int skrin = 0;                //номер отображаемого экрана
boolean ii = 0;               //запоминание нажатой клавиши
int sk = 0;                   //промежуточная переменная номера экрана
int I1;                       //измеренная величина тока генератора
int I2;                       //измеренная величина тока нагрузки
int Ui;                       //отображаемое напряжение бортсети   
int Massdata[9];              //массив выводимых данных
int value;                    //переменная знакогенератора
int Ah = 0;                   //накопленный заряд аккумулятора 
boolean OE = false;           //отсутствие включенного зажигания
int b;                        //объем топлива
int addr=0;                 //first address 
int k = 0;                    //адрес данных объема топлива
int r = 0;                    //адрес данных уровня заряда АКБ
int a3;                       //измеренное напряжение
int g = 0;
  //инициализация  АТ24С32 начало
  //запись байта (адрес 24С32, адрес который нужно записать, данные)
  void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    int rdata = data;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(rdata);
    Wire.endTransmission();
  }
 
  //запись страницы (адрес страницы 6 бит длинна не более 30 байт)!!! 
  //(адрес 24С32, номер страницы, данные,сколько байт писать)
  void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddresspage >> 8)); // MSB
    Wire.write((int)(eeaddresspage & 0xFF)); // LSB
    byte c;
    for ( c = 0; c < length; c++)
      Wire.write(data[c]);
    Wire.endTransmission();
  }
  //чтение байта (адрес 24С32, адрес который нужно прочитать)
  byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) rdata = Wire.read();
    return rdata;
  }
 
  
  //чтение буфера данных, разово не более 30 байт (адрес 24С32, адрес начала буфера, данные,сколько байт читать)
  void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,length);
    int c = 0;
    for ( c = 0; c < length; c++ )
      if (Wire.available()) buffer[c] = Wire.read();
  }
  //инициализация АТ24С32 конец
  
                  //начало предустановок
void setup () {
  
  Wire.begin();
  //Serial.begin(57600);   
  rtc.begin();
    
  pinMode(4, OUTPUT); //дешифратор А
  pinMode(5, OUTPUT); //дешифратор В
  pinMode(6, OUTPUT); //дешифратор С
  pinMode(7, OUTPUT); //дешифратор D
  pinMode(12, INPUT);  //K
  pinMode(13, INPUT); //SQW
   //устанавливаем режим OUTPUT
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  //инициализация DS3231 вывода SQW в режиме генерации 1кГц.
  //эта процедура нужна только 1 раз для новых часов!!!
  /*Wire.beginTransmission(0x68);
  Wire.write(0x0E);
  Wire.write(0x00); //0x00=1 Гц,0x08=1024 Гц,0x10=4096 Гц,0x18=8196 Гц
  Wire.endTransmission(); */
  // конец инициализации 
  
  //чтение АТ24С32 начало  
      b = i2c_eeprom_read_byte(0x57,k); //чтение байтa с адреса 0
     
  //чтение АТ24С32 конец 
  
}        //конец предустановок 
         // старт цикла программы
void loop () {
if (g == 0){
  I2 = analogRead (0)* 3;                    //значение тока заряда
  if(! (digitalRead(12))) {InputK = count3P; ii = 1;} else InputK = 7; //InputK в диапазоне 0-3 или 7
  a3 = analogRead (3);
  //для записи расхода топлива необходимо знать момент отключение зажигания
  if(a3 > 695) {OE = true;} else {OE = false;} //1023->14v 695->9,5v
  Ui = (a3 * 16)/10; //масштабирование напряжение бортсети - проверить точность!  
  }
  g = g + 1;
  //индикация - 74145 начало
  if(count3P == 10) count3P = 0; //сброс счетчика разрядов после 9 
digitalWrite(4, (bitRead((count3P), (0)))); //управление "1" 74145
digitalWrite(5, (bitRead((count3P), (1)))); //управление "2" 74145
digitalWrite(6, (bitRead((count3P), (2)))); //управление "4" 74145
digitalWrite(7, (bitRead((count3P), (3)))); //управление "8" 74145
          
     // 74145 конец 
   
     //обработка клавиатуры начало
     //если нога D12 = 0 значит нажата кнопка 
       
   //меню работы начало 
   // (InputK ==0) //"+"
   // (InputK ==1) //"-"
   // (InputK ==2) //Запись 
   // (InputK ==3) //подтверждение
   
   if (ii)            // если кнопка была нажата
   { 
   if ((skrin == 0)&&(InputK == 3)) razr = 1; else razr =0;//разрешение корректировки уровня топлива 
   if ((skrin == 0)&&(InputK == 0)&&(razr = 1)) rash = rash + (1/10);//кол-во топлива в баке +0.1Л 
   if ((skrin == 0)&&(InputK == 1)&&(razr = 1)) rash = rash - (1/10);//кол-во топлива в баке -0.1Л
   if ((skrin == 0)&&(InputK == 2)&&(razr = 1)) rashod = rash; razr = 0;//запись уровня топлива в баке 
  
   if (count3P == 0)                   //счетчик разрядов в 0 
   {  
   if (skrin == 0) sk = 1;  //экран 0 
   if (skrin == 1) sk = 2;  //экран 2
   if (skrin == 2) sk = 0;  //экран 0
   } 
   
   if (count3P)                       //счетчик разрядов в 1
   {    
   if (skrin == 1) sk = 0; //экран 0
   if (skrin == 0) sk = 2; //экран 2
   if (skrin == 2) sk = 1; //экран 1
   }
    skrin = sk;                        //присвоение номера экрана                    
   } 
  ii = 0;                            // сброс флага нажатия кнопки
  
   //меню работы конец   
  
     //обработка клавиатуры конец
     
     //таблица конверсии начало
 if (Massdata[count3P]==48) value = 63; //0* цифра
 if (Massdata[count3P]==148) value = 191;//0.
 if (Massdata[count3P]==49) value = 6;  //1
 if (Massdata[count3P]==149) value = 134;//1.
 if (Massdata[count3P]==50) value = 91; //2
 if (Massdata[count3P]==150) value = 219;//2.
 if (Massdata[count3P]==51) value = 79; //3
 if (Massdata[count3P]==151) value = 207;//3.
 if (Massdata[count3P]==52) value = 102;//4 
 if (Massdata[count3P]==152) value = 230;//4.
 if (Massdata[count3P]==53) value = 109;//5
 if (Massdata[count3P]==153) value = 237;//5.
 if (Massdata[count3P]==54) value = 125;//6
 if (Massdata[count3P]==154) value = 253;//6.
 if (Massdata[count3P]==55) value = 7;  //7
 if (Massdata[count3P]==155) value = 135;//7.
 if (Massdata[count3P]==56) value = 127;//8 
 if (Massdata[count3P]==156) value = 255;//8. 
 if (Massdata[count3P]==57) value = 111;//9
 if (Massdata[count3P]==157) value = 239;//9.
 if (Massdata[count3P]==45) value = 64; //"-"
 if (Massdata[count3P]==65) value = 119;//A
 if (Massdata[count3P]==67) value = 57; //L
 if (Massdata[count3P]==76) value = 56; //C
 if (Massdata[count3P]==80) value = 115;//P
 if (Massdata[count3P]==85) value = 62; //U 
 if (Massdata[count3P]==2) value = 116; //h 
 if (Massdata[count3P]==0) value = 0;  //пустое знакоместо
      //таблица конверсии конец
    
     
     // 74HC595 наачало
    int numberToDisplay = (value);    // value - код символа выводимого на отображение
    digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW
    shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay); // передаем последовательно на dataPin
    digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах
    
    
    //74HC595 конец
  
            //обработка термометра
  if (skrin == 1){    
  byte i;           // i-байтовая пременная
  byte present = 0; //байтовая пременная present = 0;
  byte type_s;      // байтовая пременная  type_s;
  byte data[12];    // массмв данных  data длинной в 13 байт 
  byte addr[8];     // массмв данных  addr длинной в 9 байт 
  float celsius =0;    //пременная с плавющей точкой celsius
 
   
  if ( !ds.search(addr)) {
  
  ds.reset_search();                    // функция поиска адреса
    delay(250);                           //задержка 250 мс 
    return;                               // возврат 
  }                                       //конец подпрограммы опроса доступныз термометров
  
   for( i = 0; i < 8; i++) {             // цикл опроса от 0 до 8
 
  }                                     // конец подпрограммы 
                                        
 
      type_s = 0;              
  if (started == false)    // если старта еще не было 
   { present = ds.reset(); // устанавливаем сброс ноги где подключен термометр
     ds.select(addr);      //устанавливаем начальный адрес из массива 
     ds.write(0x4E);       //отправляем команду записи в байты 2,3.4 ОЗУ 
     ds.write(0x4B);       //записываем байт 2 TH максимальная температура +75"С
     ds.write(0x05);       //записываем байт 3 TL минимальная температура +5"С
     ds.write(0x0f);       //записываем байт конфигурации; 6f-> 12bit точность, 0f->9bit точность 
     started = true;       // инициализация завершена 
   } 
 
  ds.reset();              // сброс
  ds.select(addr);         // установка начального адреса
  ds.write(0x44, 1);       // старт преобразования температуры
  
  delay(200);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();   //сброс ноги Атмеги  
  ds.select(addr);        //установка адреса 
  ds.write(0xBE);         // запрос температуры из термометра
 
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
 
  }
   
  //Преобразование данных в текущее значение температуры
  
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    
  }
  celsius = int((float)raw / 16.0);       //преобразование температуры в градусы цельсия
  
           //разбивка температуры на отдельные разряды начало
  char buff[2];           
  itoa(celsius,buff,10); 
  if(buff[2] == 16){Massdata [5] = 0; Massdata [6] = 0; Massdata [7] = (buff[0]);} //диапазон от 0 до +9С
  if(buff[2] == 0) {Massdata [5] = 0; Massdata [6] = (buff[0]); Massdata [7] = (buff[1]);} // от -9С до -1С и от +10С и выше
  if(buff[2] > 16) {Massdata [5] = buff[0]; Massdata [6] = buff[1]; Massdata [7] = buff[2];} //от -10С и ниже
  }
             //разбивка температуры на отдельные разряды конец 
             //конец термометра
      
      
    //отображение напряжения бортсети
    if (skrin == 1) {
  if (Ui < 1023){Massdata [0] = int(((String(Ui)).charAt(0))+100);} else {Massdata [0] = int((String(Ui)).charAt(0));}
  if (Ui > 1023){Massdata [1] = int(((String(Ui)).charAt(1))+100);} else {Massdata [1] = int((String(Ui)).charAt(1));}
  Massdata [2] = int((String(Ui)).charAt(2));}
  
  
  if (skrin == 2) {
  int P; //мощность в ваттах
  I1 = analogRead (1)* 3;                 //значение тока нагрузки
  P = (round(I1)/96) * (round(Ui)/100);   //мощность потребителей округленно
  Massdata [5] = int(String(P).charAt(0));
  Massdata [6] = int(String(P).charAt(1));
  Massdata [7] = int(String(P).charAt(2));}
  
  
                        // обработка часов
    DateTime now = rtc.now();              //получение текущего времени
   
                           //подготовка данных для массива
    if (skrin == 0) {   
    if (now.hour() < 10) Massdata [0] = 48; else Massdata [0] = int(String(now.hour()).charAt(0));
      Massdata [1] = int(String(now.hour()).charAt(0));
    if (now.minute() < 10) Massdata [3] = 48; else Massdata [3] = int(String(now.minute()).charAt(0));
      Massdata [4] = int(String(now.minute()).charAt(0));
    if (bitRead(now.second(),0)) Massdata [2] = 45; else Massdata [2] = 0; //исп. бита 0 секунд для мигаюния секундного разделителя 
    }
                    //значение тока заряда
    if((OE == true)&&(now.second()==59)) Ah = Ah + round(I2/6000);  //расчет ампер часов-интервал минута 
      Massdata [0] = int((String(Ah).charAt(0))+100);
      Massdata [1] = int(String(Ah).charAt(1));
         
//начало записи накопленного заряда АКБ в АТ24С32 по адресу - "r"
if(OE == false) {
      i2c_eeprom_write_byte(0x57,r,Ah);
      delay(10);}
         //конец записи накопленного заряда АКБ в АТ24С32 по адресу - "r"
                        //конец обработки часов
 
 
// подсчет и отбражение счетчика расхода; rashod = 50 (5 литров); rash -пременная объема
if ( (digitalRead (2))) //сюда подключен расходомер
   { 
   if (! count2I)          //счетчик переключения разрядов 
      {
       count2P = count2P+1;
       count2I = 1;
      }
   }
else
   {
   count2I=0;
   }
 if (count2P == 217) b = b - 1;    //уменьшение расхода после 217 импульсов на 1 (0,1литр)
 if(count2P == 218) count2P = 0;   //сброс счетчика расхода после 218
 
 Massdata [6] = int(((String(b)).charAt(0))+100);      //единицы литров
 Massdata [7] = int((String(b)).charAt(1));      //десятые части литра
 if(OE == false){
 i2c_eeprom_write_byte(0x57,k,b);
 delay(10); 
 } 
  //конец счетчика расхода   
 
                      //массивы выходной информации 
 if (skrin == 0){
 Massdata [5] = 0;  //пустое место
 Massdata [8] = 76; //L 
 else if (skrin == 1) { 
  Massdata [3] = 85; //U 
  Massdata [4] = 0;  //пустое место
  Massdata [8] = 67; //С 
}
  else
  { 
   Massdata [2] = 65;//A 
   Massdata [3] = 2; //h 
   Massdata [4] = 0;  //пустое место
   Massdata [8] = 80; //P 
}
 
 
 //delay(1000); //через какое время выводить
 count3P = count3P+1;
if(g == 9) g = 0; 
}
 
toxikaciya
Offline
Зарегистрирован: 11.04.2016

Вставка кода.

По теме: Proteus не вытягивает реальную частоту ардуино.

serg-abeliar
Offline
Зарегистрирован: 21.07.2016

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

serg-abeliar
Offline
Зарегистрирован: 21.07.2016

Итак теперь вопросы более конкретные: 1 Отсутствие прерываний для получения текущего времени, работы с клавиатурой из за маленького времени основного цикла приводит к проблемам. Время цикла увеличивать нельзя - динамическая 9 разрядная индикация. 2 Кусок кода вставленный из примера для DS18B20 надо как то оптимизировать - у меня 1 датчик и адрес я его знаю. Подктньте советов а лучше примеров пожалуйста. 

victorv
Offline
Зарегистрирован: 31.07.2015

Здравствуйте , чуствую , что туплю - помогите сменить инверсию цвета при выводе на печать, надо чтоб дорожки были прозрачными...задолбался.Протеус 8.4