Добавить память программ к Nano (Atmega328)

Kazanova
Offline
Зарегистрирован: 29.01.2015

Добрый день!

На стадии завершения проекта столкнулся с нехваткой памяти программ, не хватает буквальо 1-2 кб. Можно ли часть программы как то пристроить во внутреннюю еепром или во внешнюю I2C ?  

Используются библиотеки

include <Wire.h>
#include <DS1307.h>
#include <TinyGPS++.h>
#include <OneWire.h>

#include <DallasTemperature.h>

#include "U8glib.h".

 

Может быть есть какие то тонкости их использования в плане экономии места? 

Заранее спасибо!

bwn
Offline
Зарегистрирован: 25.08.2014

Например выкинуть DallasTemperature.h и сделать просто на Wire (примеры есть и не сложнее чем с либой) в районе 1-1,5К освободите. Та же судьба с DS1307.h, тоже 1К примерно. Остальные не знаю, не работал с ними.

toc
Offline
Зарегистрирован: 09.02.2013

программу можно хранить на sd карте. http://bitlash.net

bwn
Offline
Зарегистрирован: 25.08.2014

toc пишет:
программу можно хранить на sd карте. http://bitlash.net

Я в аглицкой мове не силен, а как ее оттуда запускать?

Kazanova
Offline
Зарегистрирован: 29.01.2015

при компиляции компилятор прописывает всю либу или только те функции, которые используются ?

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

Как уже говорили, избався от <DS1307.h> и <DallasTemperature.h>, они откровенно лишние. И ещё доработай напильником остальные библиотеки, там обычно есть что выкинуть в конкретной задаче.

Kazanova
Offline
Зарегистрирован: 29.01.2015

Избавился от ненужного, попилил лишнее,  добавил функционал и опять уперся в память.   такие мысли:

 

В отличии от УНО, нана программируется  по последовательному порту, а в память живет порядка 2 кб загрузчика. У УНЫ я так понял на программирование свой процессор, который шьет по СПЙ.

1) Взять уну, выдрать из нее мегу,  проводками соединить ножки СПЙ и питания и шить как уно.  Не будет ли различий для компилятора ?   У уно меньше ножек портов чем у нано, не будет ли проблем ?

 

2) Если Ардуино ИДЕ генерит где то хекс файл - зашить его с помощью любого спй программатора , хоть понипрогом.

Как обойти ограничение по память в ИДЕ  в этом случае ? или просто указывать плату Уно и не париться ?

 

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

bwn
Offline
Зарегистрирован: 25.08.2014

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

Kazanova
Offline
Зарегистрирован: 29.01.2015

Выкладываю.   Панель приборов для катера.  Графика, цифры, измерения.   В проекте много вкладок,  а все просто в один текстовик перекопировал, если провильно понимаю.


//Проект панели приборов для катера

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <Wire.h>
#include <DS1307L.h>
#include <TinyGPS++.h>
#include <OneWire.h>
//-----------------------------------------------------------------------
//LCD
#include "U8glib.h";   //Мегабиблиотека 
U8GLIB_T6963_240X128 u8g(2, 13, 4, 5, 6, 7, 8, 9, 10, A2, A0, A1, 11); //Пины дисплея 7,8,9,10,11,12,13,14,15,4,6,5,16
const int Bcklt = 1; //управление подсветкой A0=14 A1=15 ...
//pinMode (Bcklt,output);
//digitalWrite (Bcklt,HIGH);  // Включить подсветку
//digitalWrite (Bcklt,LOW);   // Выключить подсветку

//=============================================================================
//SETUP
void setup(void) 
{
 RTCsetup();  //Настройка RTC 
 GPSSetup();  //Настройка ЖПС
 RtcRamLoad();//Восстанавливаем данные из RTC
 DS18B20();
 DS18B20();
 DS18B20();
 DS18B20(); //Считываем температуры
 PresSetup();//Настройка бародатчика
 

 pinMode (Bcklt,OUTPUT);
 digitalWrite (Bcklt,HIGH);  // Включить подсветку
}




//=============================================================================
//Основной цикл
void loop(void) {

 //if (Buttons()!=2) {RtcRamLoad();}
  
  RTCGetTime();  //Запрос времени
  Tach();        //счет тахометра
  Speed();      //счет спидометра
  Voltage();    //запрос напряжения
  HRS();        //запрос моточасов
  GPS();        //Запрос ЖПС
  ButtCheck();  //Проверка кнопок
  DS18B20();    //Температуры
  Pres();       //Давление
 

  RtcRamSave(); //Cохраняем все
  
  Draw();       //Отрисовываем
 
}
 
//Переменные, константы, определения
//----------------------------------------------------------------
//Для вывода моточасов
int       hrsOb=0,            //Порог оборотов счета моточасов
          hrsDayM=0,hrsDayH=0, //моточасы и мотоминуты сут
          hrsAllM=0,hrsAllH=0; //моточасы и мотоминуты общ
unsigned long      hrsBuf=0;
const int odoX=159, odoY=0, odoW=81, odoH=51;
//----------------------------------------------------------------
//Для вывода GPS данных
float GpsLong=0,GpsLat=0,GpsLong0=0,GpsLat0=0;
byte speedV=0,GpsSpeed=0,GpsDay=0,GpsMonth=0,GpsHr=0,GpsMin=0;
word GpsYear=0,GpsSat=0,GpsDim=0,GpsDist=0,GpsChksum=0;
unsigned long odoDay=0,odoAll=0;
const int speedMax=50,
          speedX=80, speedY=0,
          speedW=80, speedH=51,
          speedStrX=6,speedStrY=46;          
//----------------------------------------------------------------
//Для вывода оборотов
float obor=0,obor1=0,
      oborDam=7.1;             //Аварийные параметры
const int oborMax=7000,        //?
          oborX=59, oborY=50,
          oborW=122, oborH=78,
          oborStrX=19,oborStrY=50,
          oborBarX=5,oborBarY=60,
          oborBarW=oborW-(2*oborBarX),oborBarH=12;
//----------------------------------------------------------------          
//Для вывода Напряжения
float volt=0, voltDiv=49.17; //коэффициент коррекции напряжения.
int voltDam0=11, voltDam1=15;   //Аварийные параметры
const int 
          voltX=oborX+61,  voltY=108,
          voltW=61,  voltH=20,
          voltStrX=voltX+42,  voltStrY=voltY+13,
          voltStr1X=voltX+5,  voltStr1Y=voltY+16;
//----------------------------------------------------------------
//Для вывода температур, давления
float tempAir=0,tempEng=0,tempWat=0;
int baro=760;
byte tempI=0;
const int tempEngDam=70,        //Аварийный параметр
          tempX=180, tempY=50,
          tempW=60, tempH=78,
          tempStrX=3,tempStrY=3,
          tempEX=oborX,tempEY=108,tempEW=62,tempEH=20;
//----------------------------------------------------------------
//Для вывода времени          
char* RTCstring="00-00";
char* RTCDatastring="01-01-15   ";
char* RTCDaystring="--";
int rtc[7];
byte rr[7];          
const int RTCX=0, RTCY=0,
          RTCW=81, RTCH=51,
          RTCStrX=16,RTCStrY=24,
          RTCStr1X=6,RTCStr1Y=45,
          RTCStr2X=6,RTCStr2Y=19;
//----------------------------------------------------------------








//----------------------------------------------------------------    
//Карта RTC RAM
const byte
  hrsDayRam = 10;           //2 байта



// обработчик кнопок возвращает 0=ничего не нажато, кнопки 1-3 соотв-но
byte Buttons()
{
int buttAdc=analogRead(6);
 if (buttAdc>1000) return 0;
 delay (100);
 buttAdc=analogRead(6);
 if ((buttAdc<800)&&(buttAdc>600)) return 1; 
 if ((buttAdc<=600)&&(buttAdc>400)) return 2; 
 if (buttAdc<=400) return 3;  
}

//===========================================================================
// проверка и обработка нажатий
void ButtCheck()
{
//Обнуление суточных параметров по нажатию But3
  if (Buttons()==3) { delay(1000);}                            //Обнуление моточасов сут
  if (Buttons()==3) { hrsDayM=0; hrsDayH=0; hrsBuf=millis();  //Обнуление моточасов сут
                      odoDay=0;                              //Обнуление суточного одометра  
      //              hrsAllM=0; hrsAllH=0;                 //Обнуление моточасов общ
                      odoAll=0;                            //Обнуление общего одометра 
                      
  }
//-----------------------------------------------------------------------------


                      
}
 





//=============================================================================
//Процедуры DRAW отрисовки
void Draw(void)
{ 
 u8g.firstPage();  do { 
//=======================================================
//Обороты
u8g.drawRFrame(oborX, oborY, oborW, oborH, 8);
if (obor1>=oborDam) {u8g.drawRBox(oborX, oborY, oborW, oborH-20, 8);u8g.setColorIndex(0);} //Аварийно
//u8g.setFont(u8g_font_fub42n);
u8g.setPrintPos(oborStrX+oborX,oborStrY+oborY);
u8g.print(obor1,1);
u8g.setColorIndex(1);
//=======================================================
//Напряжение Бортсети
if ((volt<=voltDam0)||(volt>=voltDam1)) {u8g.drawRBox(voltX, voltY, voltW, voltH, 8); u8g.setColorIndex(0);} //Аварийно
u8g.drawRFrame(voltX, voltY, voltW, voltH, 8);
u8g.setFont(u8g_font_micro);
u8g.drawStr(voltStrX,voltStrY,"Volt");
u8g.setFont(u8g_font_helvB14n);
if (volt>10) { u8g.setPrintPos(voltStr1X,voltStr1Y);}
     else { u8g.setPrintPos(voltStr1X+8,voltStr1Y);}
u8g.print(volt,1);
u8g.setColorIndex(1);
//=======================================================
//Температура двигателя
if (tempEng>=tempEngDam) {u8g.drawRBox(tempEX, tempEY, tempEW, tempEH, 8);u8g.setColorIndex(0);} //Аварийно
u8g.drawRFrame(tempEX, tempEY, tempEW, tempEH, 8);
u8g.setFont(u8g_font_micro);
u8g.drawStr(4+tempEX,12+tempEY,"Eng");
u8g.setFont(u8g_font_helvB14n);
if (tempEng>=10){u8g.setPrintPos(20+tempEX,16+tempEY);}
if (tempEng<=-10) {u8g.setPrintPos(16+tempEX,16+tempEY);}
if ((tempEng>=0)&&(tempEng<10)){u8g.setPrintPos(30+tempEX,16+tempEY);}
if ((tempEng>-10)&&(tempEng<0)) {u8g.setPrintPos(24+tempEX,16+tempEY);}
u8g.print(tempEng,1);
u8g.setColorIndex(1);
//=======================================================
//Температура воздуха+температура воды+давление+топливо
u8g.drawRFrame(tempX, tempY, tempW, tempH, 8);
u8g.drawRFrame(tempX, tempY+58,tempW, 20, 8);
u8g.setFont(u8g_font_micro);
u8g.drawStr(tempX+tempStrX,tempY+tempStrY+12,"AIR");
u8g.drawStr(tempX+tempStrX,tempY+tempStrY+30,"WAT");
u8g.drawStr(tempX+tempStrX,tempY+tempStrY+48,"PRES");
u8g.drawStr(tempX+tempStrX,tempY+tempStrY+68,"FUEL");
u8g.setFont(u8g_font_helvB14n);
if (tempAir>=10){u8g.setPrintPos(tempX+tempStrX+18,tempY+tempStrY+15);}
if (tempAir<=-10) {u8g.setPrintPos(tempX+tempStrX+14,tempY+tempStrY+15);}
if ((tempAir>=0)&&(tempAir<10)){u8g.setPrintPos(tempX+tempStrX+28,tempY+tempStrY+15);}
if ((tempAir>-10)&&(tempAir<0)) {u8g.setPrintPos(tempX+tempStrX+22,tempY+tempStrY+15);}
u8g.print(tempAir,1);
if (tempWat>=10){u8g.setPrintPos(tempX+tempStrX+18,tempY+tempStrY+33);}
if (tempWat<=-10) {u8g.setPrintPos(tempX+tempStrX+14,tempY+tempStrY+33);}
if ((tempWat>=0)&&(tempWat<10)){u8g.setPrintPos(tempX+tempStrX+28,tempY+tempStrY+33);}
if ((tempWat>-10)&&(tempWat<0)) {u8g.setPrintPos(tempX+tempStrX+22,tempY+tempStrY+33);}
u8g.print(tempWat,1);
u8g.setPrintPos(tempX+tempStrX+23,tempY+tempStrY+51);
u8g.print(baro);
u8g.drawStr(tempX+tempStrX+18,tempY+tempStrY+72,"///////");
//=======================================================
//Спидометер
u8g.drawRFrame(speedX, speedY, speedW, speedH, 8);
//u8g.setFont(u8g_font_fub42n);
if ((speedV<98)&&(GpsSat>3))
     {
    if (speedV<10) {u8g.setPrintPos(speedStrX+speedX+20,speedStrY+speedY);}
    else {u8g.setPrintPos(speedStrX+speedX,speedStrY+speedY);}
    u8g.print(speedV);
    }
if ((speedV==98)||(GpsSat<4)&&(speedV!=99))
     {u8g.setPrintPos(speedStrX+speedX+47,speedStrY+speedY-4);u8g.setFont(u8g_font_helvB14n);u8g.print(GpsSat);
      u8g.setPrintPos(speedStrX+speedX-1,speedStrY-30);u8g.setFont(u8g_font_micro);u8g.print(" GPS DATA SEARCH");
      u8g.setPrintPos(speedStrX+speedX-1,speedStrY-10);                            u8g.print(" SATTELITES"); 
     } 
if (speedV==99)
     {u8g.setPrintPos(speedStrX+speedX-1,speedStrY-28);u8g.setFont(u8g_font_micro);u8g.print("   GPS Receiver");
      u8g.setPrintPos(speedStrX+speedX-1,speedStrY-10);                            u8g.print("      DAMAGE"); 
     }        
//=======================================================
//Спутники
 u8g.setPrintPos(oborX+6,oborY+9);u8g.setFont(u8g_font_micro);u8g.print(GpsSat);  
//Checksum
 u8g.setPrintPos(oborX+6,oborY+20);u8g.print(GpsChksum);
 
//=======================================================
//Часы
u8g.drawRFrame(RTCX, RTCY, RTCW, RTCH, 8);
//u8g.setFont(u8g_font_helvB18n);
u8g.setFont(u8g_font_helvB14n);
u8g.drawStr(RTCX+RTCStrX,RTCY+RTCStrY,RTCstring);
u8g.setFont(u8g_font_helvB14n);
u8g.drawStr(RTCX+RTCStr1X,RTCY+RTCStr1Y,RTCDatastring);
u8g.setFont(u8g_font_micro);
u8g.drawStr(RTCX+RTCStr2X,RTCY+RTCStr2Y,RTCDaystring);
//=======================================================
//Одометр+моточасы сут
u8g.drawRFrame(odoX, odoY, odoW, odoH, 8);
u8g.setFont(u8g_font_micro);
u8g.drawStr(odoX+6,odoY+18,"ODO");
u8g.drawStr(odoX+6,odoY+41,"HRS");
//------------------------------
//суточный одометр
//u8g.setFont(u8g_font_helvB18n);
u8g.setFont(u8g_font_helvB14n);
u8g.setPrintPos(odoX+20,odoY+24);
float odoDayf=odoDay/100;
odoDayf=odoDayf/10;
if (odoDay<100000) {u8g.print("0");}
if (odoDay<10000) {u8g.print("0");}
u8g.print(odoDayf,1);
//u8g.setPrintPos(0,80);u8g.print(GpsDist); //Для теста Дистанции
//------------------------------
//Общий одометр
u8g.setPrintPos(5,100);
if (odoAll<1000000) {u8g.print("0");}
if (odoAll<100000) {u8g.print("0");}
if (odoAll<10000) {u8g.print("0");}
u8g.print(odoAll/1000);
//------------------------------
//моточасы
u8g.setFont(u8g_font_helvB14n);
u8g.setPrintPos(odoX+26,odoY+45);
if (hrsDayH<10) {u8g.print("0");}
u8g.print(hrsDayH);
if (obor>hrsOb) {u8g.print(".");} else {u8g.print(":");}
if (hrsDayM<10) {u8g.print("0");}
u8g.print(hrsDayM);
//------------------------------
//Моточасы общ
u8g.setPrintPos(5,124);
if (hrsAllH<1000){u8g.print("0");}
if (hrsAllH<100) {u8g.print("0");}
if (hrsAllH<10)  {u8g.print("0");}
u8g.print(hrsAllH);
//=======================================================

} while( u8g.nextPage() ); }  

//Работа с TinyGPS++
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;

void GPSSetup()
{
 Serial.begin(GPSBaud);
}
void txOff()
{   pinMode(1, OUTPUT);byte b=UCSR0B;b-=_BV(TXEN0);UCSR0B=b;}  
void txOn()
{   byte b=UCSR0B;b+=_BV(TXEN0);UCSR0B=b;}  
//-------------------------------------------------------------------
void GPS()
{
   while (Serial.available() )
    gps.encode(Serial.read());
    if (gps.location.isValid()) 
      {GpsLat=gps.location.lat(); GpsLong=gps.location.lng();
                          if (GpsLat0!=0) {GpsDist=gps.distanceBetween(GpsLat,GpsLong,GpsLat0,GpsLong0);
                          if ((GpsDist>1)&&(GpsSat>4)){odoDay+=GpsDist;odoAll+=GpsDist;}
                          if (odoDay>999999) {odoDay=0;} if (odoAll>9999999) {odoAll=0;}}
        
       GpsLat0=GpsLat; GpsLong0=GpsLong;}       
    else {GpsLat=0; GpsLong=0;GpsDist=0;}
    
   if (gps.date.isValid()) {GpsDay=gps.date.day();GpsMonth=gps.date.month();GpsYear=gps.date.year();}
    else {GpsDay=0;GpsMonth=0;GpsYear=0;}
   if (gps.time.isValid()){GpsHr=(gps.time.hour());GpsMin=(gps.time.minute());}
    else {GpsHr=99;GpsMin=99;}
   if (gps.speed.isValid()){GpsSpeed=gps.speed.kmph();}
    else {GpsSpeed=98;}                              //Если данных нет, скорость 98
   GpsSat=gps.satellites.value();
   GpsDim=gps.hdop.value(); 
   GpsChksum=gps.failedChecksum();

    

 //  GpsDist=100;
  //  odoDay+=GpsDist;odoAll+=GpsDist;
 //   if (odoDay>999999) {odoDay=0;} if (odoAll>9999999) {odoAll=0; }

      

  smartDelay(600);
  if (millis() > 5000 && gps.charsProcessed() < 10)  {  GpsSpeed=99; }    //если не обнаружен GPS GpsSpeed=99

}

static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
   while (Serial.available())
     gps.encode(Serial.read());
  } while (millis() - start < ms);
}








//Работа с DS18B20
OneWire  ds(12); //Ножка DS
float celsius;
void DS18B20()
{
 getDS18B20();
 tempI ++;
 if (tempI==1) tempEng=celsius;
 if (tempI==2) tempAir=celsius;
 if (tempI==3) tempWat=celsius;
 if (tempI==4) tempI=0;
  
}  
void getDS18B20()
{ byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
 
  if ( !ds.search(addr)) {ds.reset_search();delay(250);return;}
  if (OneWire::crc8(addr, 7) != addr[7]) {celsius = 999;return;}
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  delay(94);     // maybe 750ms is enough, maybe not
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad


  for ( i = 0; i < 9; i++) {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
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;

}

//Счет моточасов если обороты выше заданных 

void HRS()
{
  if (obor>hrsOb) 
  {   
  if (hrsBuf==0) {hrsBuf=millis();}
  if ((millis()-hrsBuf)>60000) {hrsBuf=(hrsBuf+60000); hrsDayM ++; hrsAllM ++;}  // каждые 60 сек
  if (hrsDayM>59) {hrsDayM=0;hrsDayH ++;} // пасклад на часы и минуты суточный 
  if (hrsDayH>99) {hrsDayH=0;}
  if (hrsAllM>59) {hrsAllM=0;hrsAllH ++;} // пасклад на часы и минуты общий 
  if (hrsAllH>9999) {hrsAllH=0;}
  } 
  else {hrsBuf=0;}
 
} 
void RtcRamLoad()    //загружаем и расписываем данные из RCT RAM 
{

  Wire.beginTransmission(DS1307_CTRL_ID);
  Wire.write(10);                          //с алреса 10
  Wire.endTransmission();  
  Wire.requestFrom(DS1307_CTRL_ID, 20);  //запрос 20 данных 
  hrsDayM=Wire.read();
  hrsDayH=Wire.read();
  hrsAllM=Wire.read();
  hrsAllH=Wire.read();
  hrsAllH=((256*Wire.read())+hrsAllH);
unsigned long odoDay1=0;
  odoDay1=Wire.read();odoDay=odoDay1*1; 
  odoDay1=Wire.read();odoDay+=odoDay1*256;
  odoDay1=Wire.read();odoDay+=odoDay1*65536;
  odoDay1=Wire.read();odoDay+=odoDay1*16777216;
  odoDay1=Wire.read();odoAll=odoDay1*1;
  odoDay1=Wire.read();odoAll+=odoDay1*256;
  odoDay1=Wire.read();odoAll+=odoDay1*65536;
  odoDay1=Wire.read();odoAll+=odoDay1*16777216;

 
 
  Wire.read();
  Wire.read();
  Wire.read();
  Wire.read();
  Wire.read();
  Wire.read();
  Wire.read();
  Wire.read();
  Wire.read();
}  


//Процедуры работы с датчиком давления BMP085

#define I2C_ADDRESS 0x77 //77?

const unsigned char oversampling_setting = 3; //oversamplig (передискретизация)
const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 };
int ac1,ac2,ac3,b1,b2,mb,mc,md; 
unsigned int ac4,ac5,ac6;


void PresSetup()
{  
  bmp085_get_cal_data();
}
void bmp085_read_temperature_and_pressure(int& temperature, long& pressure);

void Pres()
{
  int  temperature = 0;
  long pressure = 0;

  bmp085_read_temperature_and_pressure(&temperature,&pressure);
  baro=(pressure/133.3);

}

void bmp085_read_temperature_and_pressure(int* temperature, long* pressure) {
   //int ut = bmp085_read_ut();
   long ut = bmp085_read_ut();
   long up = bmp085_read_up();
   long x1, x2, x3, b3, b5, b6, p;
   unsigned long b4, b7;

   //расчет температуры 
   x1 = ((long) ut - ac6) * ac5 >> 15;
   x2 = ((long) mc << 11) / (x1 + md);
   b5 = x1 + x2;
   *temperature = (b5 + 8) >> 4;
     
   //расчет давления
   b6 = b5 - 4000;
   x1 = (b2 * (b6 * b6 >> 12)) >> 11;
   x2 = ac2 * b6 >> 11;
   x3 = x1 + x2;
   //b3 = (((int32_t) ac1 * 4 + x3)<> 2;
   
   if (oversampling_setting == 3) b3 = ((int32_t) ac1 * 4 + x3 + 2) << 1;
   if (oversampling_setting == 2) b3 = ((int32_t) ac1 * 4 + x3 + 2);
   if (oversampling_setting == 1) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 1;
   if (oversampling_setting == 0) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 2;

   x1 = ac3 * b6 >> 13;
   x2 = (b1 * (b6 * b6 >> 12)) >> 16;
   x3 = ((x1 + x2) + 2) >> 2;
   b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
   b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting);
   p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;

   x1 = (p >> 8) * (p >> 8);
   x1 = (x1 * 3038) >> 16;
   x2 = (-7357 * p) >> 16;
   *pressure = p + ((x1 + x2 + 3791) >> 4);
}


unsigned int bmp085_read_ut() {
  write_register(0xf4,0x2e);
  delay(5); //дольше чем 4.5 мс 
  return read_int_register(0xf6);
}

void  bmp085_get_cal_data() {
  ac1 = read_int_register(0xAA);
  ac2 = read_int_register(0xAC);
  ac3 = read_int_register(0xAE);
  ac4 = read_int_register(0xB0);
  ac5 = read_int_register(0xB2);
  ac6 = read_int_register(0xB4);
  b1 = read_int_register(0xB6);
  b2 = read_int_register(0xB8);
  mb = read_int_register(0xBA);
  mc = read_int_register(0xBC);
  md = read_int_register(0xBE);
}


long bmp085_read_up() {
  write_register(0xf4,0x34+(oversampling_setting<<6));
  delay(pressure_waittime[oversampling_setting]);
  
  unsigned char msb, lsb, xlsb;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(0xf6);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
  while(!Wire.available()) {
    // ожидание 
  }
  msb = Wire.read();
  while(!Wire.available()) {
    // ожидание
  }
  lsb |= Wire.read();
  while(!Wire.available()) {
    // ожидание
  }
  xlsb |= Wire.read();
  return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting);
}

void write_register(unsigned char r, unsigned char v)
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);
  Wire.write(v);
  Wire.endTransmission();
}

char read_register(unsigned char r)
{
  unsigned char v;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
  while(!Wire.available()) {
    // ожидание
  }
  v = Wire.read();
  return v;
}

int read_int_register(unsigned char r)
{
  unsigned char msb, lsb;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 2); // read a byte
  while(!Wire.available()) {
    // ожидание
  }
  msb = Wire.read();
  while(!Wire.available()) {
    // ожидание
  }
  lsb = Wire.read();
  return (((int)msb<<8) | ((int)lsb));
}





void RTCsetup()
{
  DDRC|=_BV(2) |_BV(3);  // POWER:Vcc Gnd
  PORTC |=_BV(3);  // VCC PINC3
   RTC.get(rtc,true);
  if((rtc[6]<12)||(Buttons()==2)) {
    RTC.stop();
    RTC.set(DS1307_SEC,0);
    RTC.set(DS1307_MIN,2);
    RTC.set(DS1307_HR,5);
    RTC.set(DS1307_DOW,7);
    RTC.set(DS1307_DATE,2);
    RTC.set(DS1307_MTH,2);
    RTC.set(DS1307_YR,15);
    RTC.start();
  }
  RTC.start();
 // RTC.SetOutput(DS1307_SQW32KHZ);


}

void RTCGetTime()
{ 
  RTC.get(rtc,true);
/*
//Секунды  
  if (rtc[0]>=10)  
  { RTCstring[6]=char(48+(rtc[0]/10));
    RTCstring[7]=char(48+(rtc[0]-(rtc[0]/10)*10));
  }
  else 
  {
    RTCstring[6]='0';
    RTCstring[7]=char(48+(rtc[0]));;
  }
    RTCstring[5]=':';
*/

//Минуты  
    if (rtc[1]>=10)  
  { RTCstring[3]=char(48+(rtc[1]/10));
    RTCstring[4]=char(48+(rtc[1]-(rtc[1]/10)*10));
  }
  else 
  {
    RTCstring[3]='0';
    RTCstring[4]=char(48+(rtc[1]));;
  }

//Часы  
    if (rtc[2]>=10)  
  { RTCstring[0]=char(48+(rtc[2]/10));
    RTCstring[1]=char(48+(rtc[2]-(rtc[2]/10)*10));
  }
  else 
  {
    RTCstring[0]='0';
    RTCstring[1]=char(48+(rtc[2]));;
  }
    RTCstring[2]=':';
//Дата  
   if (rtc[4]>=10)  
  { RTCDatastring[0]=char(48+(rtc[4]/10));
    RTCDatastring[1]=char(48+(rtc[4]-(rtc[4]/10)*10));
  }
  else 
  {
    RTCDatastring[0]=char(48);
    RTCDatastring[1]=char(48+(rtc[4]));;
  }
    RTCDatastring[2]='.';
   if (rtc[5]>=10)  
  { RTCDatastring[3]=char(48+(rtc[5]/10));
    RTCDatastring[4]=char(48+(rtc[5]-(rtc[5]/10)*10));
  }
  else 
  {
    RTCDatastring[3]='0';
    RTCDatastring[4]=char(48+(rtc[5]));;
  }
    RTCDatastring[5]='.'; 
    
    RTCDatastring[6]=char(48+(rtc[6]-2000)/10);
    RTCDatastring[7]=char(48+((rtc[6]-2000)-((rtc[6]-2000)/10)*10));
    
   switch (rtc[3])
   {
    case 1: RTCDaystring="MO"; break;
    case 2: RTCDaystring="TU"; break;
    case 3: RTCDaystring="WD"; break;
    case 4: RTCDaystring="TH"; break;
    case 5: RTCDaystring="FR"; break;
    case 6: RTCDaystring="SA"; break;
    case 7: RTCDaystring="SU"; break;
   }
 
}



void RtcRamSave()
{
  Wire.beginTransmission(DS1307_CTRL_ID);  //сохраняем все моточасы
  Wire.write(hrsDayRam);
  Wire.write(hrsDayM);
  Wire.write(hrsDayH);
  Wire.write(hrsAllM);  
  Wire.write(byte(hrsAllH)); 
  Wire.write((hrsAllH)/256); 
  Wire.write(byte(odoDay));
  Wire.write(byte(odoDay/256));
  Wire.write(byte(odoDay/65536));
  Wire.write(byte(odoDay/16777216));
  Wire.write(byte(odoAll));
  Wire.write(byte(odoAll/256));
  Wire.write(byte(odoAll/65536));
  Wire.write(byte(odoAll/16777216));
  
   
   
  Wire.endTransmission();

}  
//Процедуры расписки с ЖПС данными
void Speed()
{
   speedV=GpsSpeed;
   if (GpsSpeed<5) {speedV=0;}
  
  
}  
//Инициализация


void Tach()
{
  obor +=1;
 // obor =55;
 if (obor>(oborMax/100)) obor=0;
  obor1=obor/10;
 
}
void Voltage()
{ 
  volt=analogRead(7)/voltDiv; 
  //Serial.println(analogRead(7));
}  

  
  
  


  
  
  

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

bwn
Offline
Зарегистрирован: 25.08.2014

Мдя, из простого - убрать библиотеку DS1307.h, есть где работает через Wire, как ваш BMP (примерно 1К освободит). Радикально - менять дисплей на обычный lcd, там сразу процентов 30 освободите.

Kazanova
Offline
Зарегистрирован: 29.01.2015

Ну за замену дисплея спасибо конечно :)))  

1307 смысла нет убирать,  компилятся только те функции которую пользуются.  там с десятока байт высвобождаются. тоже самое что с БМП, что с библиотекой порезанной, что ручками написанной

 

std
Offline
Зарегистрирован: 05.01.2012

В boards.txt есть определения платы, у каждой абзац текста. Надо найти плату uno или какая там используется, в соответствующем абзаце будет строка uploadmaximum или uploadlimit, хз. И цифра 30720. Или больше но меньше 32768. Поменяйте на 32768, если скетч соберётся - можно будет зашить USBASP или ArduinoISP программатором. Т. о. без загрузчика.

Лижбы оперативы хватило.

axill
Offline
Зарегистрирован: 05.09.2011

u8glib очень много ест, есть выбрать более компактный фонт

и согласен с std - шьем без загрузчика на полный размер памяти

Kazanova
Offline
Зарегистрирован: 29.01.2015

Спасибо !

 

Фонты и так все порезал, три оставил. Для отображения скорости и оборотов нужно большой юзать. Буквенный микрофонт, подписи делать.  параметры покрупнее только цифровой шрифт, ну и самый крупный 42й цифровой шрифт.  если отключить большой шрифт - все вроде упихивается.  т.е в 30720 укладываюсь,  шрифт около 1500 весит, его могу в самую последнюю очередь подключить и шить уже сторонним.

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

Можно ли другую ардуину запользовать вместо программатора ?

DeGlucker
Offline
Зарегистрирован: 23.07.2014

optiboot  жрет 512 байт вместо 2K

Kazanova
Offline
Зарегистрирован: 29.01.2015

граждане профи,  расшифровывайте плиз для новичков! желательно с картинками :)

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

Kazanova пишет:

граждане профи,  расшифровывайте плиз для новичков! желательно с картинками :)

бутлоадер себе другой вшей http://homes-smart.ru/index.php/oborudovanie/arduino/avr-zagruzchik сразу на 1.5к больше будет.

Kazanova
Offline
Зарегистрирован: 29.01.2015

Товарищи, не подскажете, откуда тут 1.5к кода набегает ?:(    Процедура работы с бародатчиком по И2С.

  сначала вызываетеся один раз PResSetup(),  а потом в цикле обновления  Pres().   Результат уходит в int baro;

//Процедуры работы с датчиком давления BMP085





#define I2C_ADDRESS 0x77 //77?

const unsigned char oversampling_setting = 3; //oversamplig (передискретизация)
const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 };
int ac1,ac2,ac3,b1,b2,mb,mc,md; 
unsigned int ac4,ac5,ac6;


void PresSetup()
{  
  bmp085_get_cal_data();
}
void bmp085_read_temperature_and_pressure(int& temperature, long& pressure);

void Pres()
{
  int  temperature = 0;
  long pressure = 0;

  bmp085_read_temperature_and_pressure(&temperature,&pressure);
  baro=(pressure/133.3);

}

void bmp085_read_temperature_and_pressure(int* temperature, long* pressure) {
   //int ut = bmp085_read_ut();
   long ut = bmp085_read_ut();
   long up = bmp085_read_up();
   long x1, x2, x3, b3, b5, b6, p;
   unsigned long b4, b7;

   //расчет температуры 
   x1 = ((long) ut - ac6) * ac5 >> 15;
   x2 = ((long) mc << 11) / (x1 + md);
   b5 = x1 + x2;
   *temperature = (b5 + 8) >> 4;
     
   //расчет давления
   b6 = b5 - 4000;
   x1 = (b2 * (b6 * b6 >> 12)) >> 11;
   x2 = ac2 * b6 >> 11;
   x3 = x1 + x2;
   //b3 = (((int32_t) ac1 * 4 + x3)<> 2;
   
   if (oversampling_setting == 3) b3 = ((int32_t) ac1 * 4 + x3 + 2) << 1;
   if (oversampling_setting == 2) b3 = ((int32_t) ac1 * 4 + x3 + 2);
   if (oversampling_setting == 1) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 1;
   if (oversampling_setting == 0) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 2;

   x1 = ac3 * b6 >> 13;
   x2 = (b1 * (b6 * b6 >> 12)) >> 16;
   x3 = ((x1 + x2) + 2) >> 2;
   b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
   b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting);
   p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;

   x1 = (p >> 8) * (p >> 8);
   x1 = (x1 * 3038) >> 16;
   x2 = (-7357 * p) >> 16;
   *pressure = p + ((x1 + x2 + 3791) >> 4);
}


unsigned int bmp085_read_ut() {
  write_register(0xf4,0x2e);
  delay(5); //дольше чем 4.5 мс 
  return read_int_register(0xf6);
}

void  bmp085_get_cal_data() {
  ac1 = read_int_register(0xAA);
  ac2 = read_int_register(0xAC);
  ac3 = read_int_register(0xAE);
  ac4 = read_int_register(0xB0);
  ac5 = read_int_register(0xB2);
  ac6 = read_int_register(0xB4);
  b1 = read_int_register(0xB6);
  b2 = read_int_register(0xB8);
  mb = read_int_register(0xBA);
  mc = read_int_register(0xBC);
  md = read_int_register(0xBE);
}


long bmp085_read_up() {
  write_register(0xf4,0x34+(oversampling_setting<<6));
  delay(pressure_waittime[oversampling_setting]);
  
  unsigned char msb, lsb, xlsb;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(0xf6);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
  while(!Wire.available()) {
    // ожидание 
  }
  msb = Wire.read();
  while(!Wire.available()) {
    // ожидание
  }
  lsb |= Wire.read();
  while(!Wire.available()) {
    // ожидание
  }
  xlsb |= Wire.read();
  return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting);
}

void write_register(unsigned char r, unsigned char v)
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);
  Wire.write(v);
  Wire.endTransmission();
}

char read_register(unsigned char r)
{
  unsigned char v;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
  while(!Wire.available()) {
    // ожидание
  }
  v = Wire.read();
  return v;
}

int read_int_register(unsigned char r)
{
  unsigned char msb, lsb;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 2); // read a byte
  while(!Wire.available()) {
    // ожидание
  }
  msb = Wire.read();
  while(!Wire.available()) {
    // ожидание
  }
  lsb = Wire.read();
  return (((int)msb<<8) | ((int)lsb));
}


 

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

А "Wire" по Вашему ничего не занимает?

Kazanova
Offline
Зарегистрирован: 29.01.2015

Я не настолько силен, но мне казалось Wire  это процедура (подпрограмма)  у которой меняются только входные параметры. или это макрос ?

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

Подпрограмма, но она же тоже в память попадает. 

Kazanova
Offline
Зарегистрирован: 29.01.2015

Так попадает один раз, а вызывается 20 раз с разными параметрами. каждый вызов 70 кб чтоли ?? 

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

так в ней куча переменных

Такой скетч 1710 байт:

#include <Wire.h>
void setup() {

}

void loop() {

}

А такой 466 байт:

void setup() {

}

void loop() {

}

 

 

Kazanova
Offline
Зарегистрирован: 29.01.2015

Не согласен. Wire.h у меня обслуживает еще RTC DS1307, так что библиотека никуда не отключается.     Убираю только приведенную часть кода, и минус полтора кб. Может в этом участке что не так ?   по сути 3 процедуры вызываются write,read, request с разными переменными величиной с байт.  При этом Wire- это аппаратный I2C и wire.write(byteconst) равносильна

ldi r16,byteconst

out TWDR,r16      Это так навскидку, ну плюс проверка состояния, туда сюда, ну это все в байт 300 на асме вписать можно, откуда полтора кило  :(

Kazanova
Offline
Зарегистрирован: 29.01.2015

А есть ли какой контроллер чтобы как атмега 328 но с большей памятью, а по корпусу такой же ? чтобы просто перепаять. все ужал, загрузчик выкинул, а всеравно не хватает пару кб :((((

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

а в каком он у вас корпусе? они разные бывают.

Kazanova
Offline
Зарегистрирован: 29.01.2015

У меня ардуино нано, распаяна на макетажной плате. на ней же дисплей, часы, датчики, ЖПС, уже корпус под все это дело сделан .   На нане стоит атмега 328 в планарном корпусе.  Вот в таком же бы корпусе с таким же назначением выводов но с большей памятью....   типа есть же наны со 168 мегой. и с 328.. вот какая нибудь 628 была бы. чтобы не ужимаясь проект закончить...

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

Kazanova
Offline
Зарегистрирован: 29.01.2015

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

 

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

KVadik, это ж как нужно поработать напильником, что бы  контроллер  в корпусе tqfp64(44) припаять на место tqfp32 ? :))

Kazanova
Offline
Зарегистрирован: 29.01.2015

Атмега 64м1 идентична по корпусу атмеге32М1. там какие то заморочки с ацп и портами. напилинг больше программный

Kazanova
Offline
Зарегистрирован: 29.01.2015

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

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

 

В терминаторе не с этого восстание роботов началось случайно ? ... :)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Kazanova, вам какая разница идентична или нет мега 64-я меге 32-й?,   эти модели контроллеров в корпусах от 44 ног, вы же хотели запаять вместо меги 328, у которой 32 ноги. Вам единственный выход приобрести уменьшенную версию ардуино мега, что-б была размерами как нано. Какой-нить Teensy 3.0, (у которого кстати 130 кило флэша), будт точно в самый раз )

Kazanova
Offline
Зарегистрирован: 29.01.2015

 

Тоже самое количество ног ведь?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Kazanova, да погуглил даташит, и впрямь есть такой зверь )

Kazanova
Offline
Зарегистрирован: 29.01.2015

Только в магазинах нету :(

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

dimax пишет:

KVadik, это ж как нужно поработать напильником, что бы  контроллер  в корпусе tqfp64(44) припаять на место tqfp32 ? :))

В моей вселенной 

Atmel ATmega16M1/32M1/64M1 TQFP32/QFN32 (7mm × 7mm) package

А "напильником дорабатывать" я про софт 

 

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

Kazanova пишет:

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

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

 

В терминаторе не с этого восстание роботов началось случайно ? ... :)

а как вы этот бутерброд программировать собираетесь (в смысле скетчи в него заливать)?

имхо, проще или с ардуино на атмел студио переучиться (там код будет оптимальнее) или на мегу2560 перейти, смотря к чему больше голова и руки заточены.

Kazanova
Offline
Зарегистрирован: 29.01.2015

Ну как, 2 платы, 2 УСБ.  скеч разделить на 2, просто по и2с данные организовать.

Асм я и так неплохо знаю,  но вот переписать графическую библиотеку или ЖПС библиотеку - это очень непросто и очень долго. Лучше нану за 100р купить :)

У меня не макетка, у меня уже оконечное устройство, типа с материнской платой, периферией, дисплеем . Ардуино мега туда уже не встанет.

Я как сделаю, отчитаюсь .

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Kazanova, а вариант тинси не рассматривали? Дороговато конечно, но так и круче)

KVadik
KVadik аватар
Offline
Зарегистрирован: 15.06.2014

dimax пишет:

KVadik, это ж как нужно поработать напильником, что бы  контроллер  в корпусе tqfp64(44) припаять на место tqfp32 ? :))

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

Kazanova
Offline
Зарегистрирован: 29.01.2015

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