Добавить память программ к Nano (Atmega328)
- Войдите на сайт для отправки комментариев
Сб, 31/01/2015 - 17:03
Добрый день!
На стадии завершения проекта столкнулся с нехваткой памяти программ, не хватает буквальо 1-2 кб. Можно ли часть программы как то пристроить во внутреннюю еепром или во внешнюю I2C ?
Используются библиотеки
include <Wire.h>
#include <DS1307.h>
#include <TinyGPS++.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "U8glib.h".
Может быть есть какие то тонкости их использования в плане экономии места?
Заранее спасибо!
Например выкинуть DallasTemperature.h и сделать просто на Wire (примеры есть и не сложнее чем с либой) в районе 1-1,5К освободите. Та же судьба с DS1307.h, тоже 1К примерно. Остальные не знаю, не работал с ними.
программу можно хранить на sd карте. http://bitlash.net
Я в аглицкой мове не силен, а как ее оттуда запускать?
при компиляции компилятор прописывает всю либу или только те функции, которые используются ?
Как уже говорили, избався от <DS1307.h> и <DallasTemperature.h>, они откровенно лишние. И ещё доработай напильником остальные библиотеки, там обычно есть что выкинуть в конкретной задаче.
Избавился от ненужного, попилил лишнее, добавил функционал и опять уперся в память. такие мысли:
В отличии от УНО, нана программируется по последовательному порту, а в память живет порядка 2 кб загрузчика. У УНЫ я так понял на программирование свой процессор, который шьет по СПЙ.
1) Взять уну, выдрать из нее мегу, проводками соединить ножки СПЙ и питания и шить как уно. Не будет ли различий для компилятора ? У уно меньше ножек портов чем у нано, не будет ли проблем ?
2) Если Ардуино ИДЕ генерит где то хекс файл - зашить его с помощью любого спй программатора , хоть понипрогом.
Как обойти ограничение по память в ИДЕ в этом случае ? или просто указывать плату Уно и не париться ?
Поменять камень - не предлагать, т.к. уже разведена и собрана плата с обвязкой. в следующий раз сразу мегу поставлю.
Вы уж лучше код выложите, может подскажут что еще запилить можно. Ну не верю я в 30К кода.
Выкладываю. Панель приборов для катера. Графика, цифры, измерения. В проекте много вкладок, а все просто в один текстовик перекопировал, если провильно понимаю.
//Проект панели приборов для катера //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #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)); }Мдя, из простого - убрать библиотеку DS1307.h, есть где работает через Wire, как ваш BMP (примерно 1К освободит). Радикально - менять дисплей на обычный lcd, там сразу процентов 30 освободите.
Ну за замену дисплея спасибо конечно :)))
1307 смысла нет убирать, компилятся только те функции которую пользуются. там с десятока байт высвобождаются. тоже самое что с БМП, что с библиотекой порезанной, что ручками написанной
В boards.txt есть определения платы, у каждой абзац текста. Надо найти плату uno или какая там используется, в соответствующем абзаце будет строка uploadmaximum или uploadlimit, хз. И цифра 30720. Или больше но меньше 32768. Поменяйте на 32768, если скетч соберётся - можно будет зашить USBASP или ArduinoISP программатором. Т. о. без загрузчика.
Лижбы оперативы хватило.
u8glib очень много ест, есть выбрать более компактный фонт
и согласен с std - шьем без загрузчика на полный размер памяти
Спасибо !
Фонты и так все порезал, три оставил. Для отображения скорости и оборотов нужно большой юзать. Буквенный микрофонт, подписи делать. параметры покрупнее только цифровой шрифт, ну и самый крупный 42й цифровой шрифт. если отключить большой шрифт - все вроде упихивается. т.е в 30720 укладываюсь, шрифт около 1500 весит, его могу в самую последнюю очередь подключить и шить уже сторонним.
Вопрос, как привязать к арудуине сторонний программатор ? или скажите где появляется результирующий HEX файл, чтобы его можно было бы в сторонний программатор использовать.
Можно ли другую ардуину запользовать вместо программатора ?
optiboot жрет 512 байт вместо 2K
граждане профи, расшифровывайте плиз для новичков! желательно с картинками :)
граждане профи, расшифровывайте плиз для новичков! желательно с картинками :)
бутлоадер себе другой вшей http://homes-smart.ru/index.php/oborudovanie/arduino/avr-zagruzchik сразу на 1.5к больше будет.
Товарищи, не подскажете, откуда тут 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)); }А "Wire" по Вашему ничего не занимает?
Я не настолько силен, но мне казалось Wire это процедура (подпрограмма) у которой меняются только входные параметры. или это макрос ?
Подпрограмма, но она же тоже в память попадает.
Так попадает один раз, а вызывается 20 раз с разными параметрами. каждый вызов 70 кб чтоли ??
так в ней куча переменных
Такой скетч 1710 байт:
#include <Wire.h> void setup() { } void loop() { }А такой 466 байт:
void setup() { } void loop() { }Не согласен. Wire.h у меня обслуживает еще RTC DS1307, так что библиотека никуда не отключается. Убираю только приведенную часть кода, и минус полтора кб. Может в этом участке что не так ? по сути 3 процедуры вызываются write,read, request с разными переменными величиной с байт. При этом Wire- это аппаратный I2C и wire.write(byteconst) равносильна
ldi r16,byteconst
out TWDR,r16 Это так навскидку, ну плюс проверка состояния, туда сюда, ну это все в байт 300 на асме вписать можно, откуда полтора кило :(
А есть ли какой контроллер чтобы как атмега 328 но с большей памятью, а по корпусу такой же ? чтобы просто перепаять. все ужал, загрузчик выкинул, а всеравно не хватает пару кб :((((
а в каком он у вас корпусе? они разные бывают.
У меня ардуино нано, распаяна на макетажной плате. на ней же дисплей, часы, датчики, ЖПС, уже корпус под все это дело сделан . На нане стоит атмега 328 в планарном корпусе. Вот в таком же бы корпусе с таким же назначением выводов но с большей памятью.... типа есть же наны со 168 мегой. и с 328.. вот какая нибудь 628 была бы. чтобы не ужимаясь проект закончить...
По распиновке 1 в 1 ? среда ардуино ее поддерживает ? штатный ботлоадер нановский можно в нее залить ?
Теоретически после доработки напильником будет поддерживать.
KVadik, это ж как нужно поработать напильником, что бы контроллер в корпусе tqfp64(44) припаять на место tqfp32 ? :))
Атмега 64м1 идентична по корпусу атмеге32М1. там какие то заморочки с ацп и портами. напилинг больше программный
Что то подумал, а не проще ли сверху напаять вторую нану, прямо на первую. типа ножки все совпадут... плату перепахивать не надо... но часть функций с первой наны, перевести на вторую.. а связать по уже используемой I2c... ???
Атмега 64м редкая оказалась, и стоит больше чем 2 наны... и будет 64 кв... медленные операции на одну нану, а дисплей на другую... частота рефреша повысится... шрифтов и мулек можно добавить.... функционал расширить.... а если надо и третью нану сверху поставить....
В терминаторе не с этого восстание роботов началось случайно ? ... :)
Kazanova, вам какая разница идентична или нет мега 64-я меге 32-й?, эти модели контроллеров в корпусах от 44 ног, вы же хотели запаять вместо меги 328, у которой 32 ноги. Вам единственный выход приобрести уменьшенную версию ардуино мега, что-б была размерами как нано. Какой-нить Teensy 3.0, (у которого кстати 130 кило флэша), будт точно в самый раз )
Тоже самое количество ног ведь?
Kazanova, да погуглил даташит, и впрямь есть такой зверь )
Только в магазинах нету :(
KVadik, это ж как нужно поработать напильником, что бы контроллер в корпусе tqfp64(44) припаять на место tqfp32 ? :))
В моей вселенной
Atmel ATmega16M1/32M1/64M1 TQFP32/QFN32 (7mm × 7mm) package
А "напильником дорабатывать" я про софт
Что то подумал, а не проще ли сверху напаять вторую нану, прямо на первую. типа ножки все совпадут... плату перепахивать не надо... но часть функций с первой наны, перевести на вторую.. а связать по уже используемой I2c... ???
Атмега 64м редкая оказалась, и стоит больше чем 2 наны... и будет 64 кв... медленные операции на одну нану, а дисплей на другую... частота рефреша повысится... шрифтов и мулек можно добавить.... функционал расширить.... а если надо и третью нану сверху поставить....
В терминаторе не с этого восстание роботов началось случайно ? ... :)
а как вы этот бутерброд программировать собираетесь (в смысле скетчи в него заливать)?
имхо, проще или с ардуино на атмел студио переучиться (там код будет оптимальнее) или на мегу2560 перейти, смотря к чему больше голова и руки заточены.
Ну как, 2 платы, 2 УСБ. скеч разделить на 2, просто по и2с данные организовать.
Асм я и так неплохо знаю, но вот переписать графическую библиотеку или ЖПС библиотеку - это очень непросто и очень долго. Лучше нану за 100р купить :)
У меня не макетка, у меня уже оконечное устройство, типа с материнской платой, периферией, дисплеем . Ардуино мега туда уже не встанет.
Я как сделаю, отчитаюсь .
Kazanova, а вариант тинси не рассматривали? Дороговато конечно, но так и круче)
KVadik, это ж как нужно поработать напильником, что бы контроллер в корпусе tqfp64(44) припаять на место tqfp32 ? :))
кстати, я вот что подумал, а не такая это уж и проблемма, берется вот такой переходник и проводочками приапаеваемся куда надо.
Это мой первый проект на ардуине, я не думал что столько кода получится. теперь примерно прикидываю на будущие по объему памяти. Сейчас надо как то оперативно решить и за новый проект браться.