Большой размер скетча. Как оптимизировать код.
- Войдите на сайт для отправки комментариев
Ср, 01/03/2017 - 21:42
После компиляции скетч весит 14346 байт.Arduino pro mini предоставляет 14336 байт, тобишь на 10 байт меньше. Помогите, подскажите что еще в коде можно изменить, как оптимизировать. Весь мозг сломал, не знаю что еще вырезать или изменить.
#include <Wire.h>
#include "Kalman.h"
#include <SPI.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
#define OLED_address 0x3c;
Adafruit_SSD1306 display(OLED_RESET);
Kalman kalmanX;
Kalman kalmanY;
uint8_t IMUAddress = 0x68;
/* IMU Data */
//int val;
int var;
int led = 8;
int red = 7;
int16_t accX;
int16_t accY;
int16_t accZ;
int16_t tempRaw;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;
double accXangle; // Angle calculate using the accelerometer
double accYangle;
double temp;
double gyroXangle = 180; // Angle calculate using the gyro
double gyroYangle = 180;
double compAngleX = 180; // Calculate the angle using a Kalman filter
double compAngleY = 180;
double kalAngleX; // Calculate the angle using a Kalman filter
double kalAngleY;
uint32_t timer;
void setup() {
pinMode(led, OUTPUT);
pinMode(red, OUTPUT);
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3c);
display.clearDisplay();
Wire.begin();
//Serial.begin(9600);
i2cWrite(0x6B, 0x00);
kalmanX.setAngle(180);
kalmanY.setAngle(180);
timer = micros();
var = 0;
}
void loop() {
while (var < 100) {
uint8_t* data = i2cRead(0x3B, 14);
accX = ((data[0] << 8) | data[1]);
accY = ((data[2] << 8) | data[3]);
accZ = ((data[4] << 8) | data[5]);
tempRaw = ((data[6] << 8) | data[7]);
gyroX = ((data[8] << 8) | data[9]);
gyroY = ((data[10] << 8) | data[11]);
gyroZ = ((data[12] << 8) | data[13]);
/* Calculate the angls based on the different sensors and algorithm */
accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
double gyroXrate = (double)gyroX / 131.0;
double gyroYrate = -((double)gyroY / 131.0);
gyroXangle += kalmanX.getRate() * ((double)(micros() - timer) / 10000); // Calculate gyro angle using the unbiased rate
gyroYangle += kalmanY.getRate() * ((double)(micros() - timer) / 10000);
kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros() - timer) / 10000); // Calculate the angle using a Kalman filter
kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros() - timer) / 10000);
timer = micros();
var++;
}
uint8_t* data = i2cRead(0x3B, 14);
accX = ((data[0] << 8) | data[1]);
accY = ((data[2] << 8) | data[3]);
accZ = ((data[4] << 8) | data[5]);
tempRaw = ((data[6] << 8) | data[7]);
gyroX = ((data[8] << 8) | data[9]);
gyroY = ((data[10] << 8) | data[11]);
gyroZ = ((data[12] << 8) | data[13]);
accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
double gyroXrate = (double)gyroX / 131.0;
double gyroYrate = -((double)gyroY / 131.0);
gyroXangle += kalmanX.getRate() * ((double)(micros() - timer) / 1000000); // Calculate gyro angle using the unbiased rate
gyroYangle += kalmanY.getRate() * ((double)(micros() - timer) / 1000000);
kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros() - timer) / 1000000); // Calculate the angle using a Kalman filter
kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros() - timer) / 1000000);
timer = micros();
/*if (Serial.available()) {
val = Serial.read();
if (val == 't')
{
Serial.println();
Serial.print("X:");
Serial.print((kalAngleX) - 180,0);
Serial.print(" ");
Serial.print("Y:");
Serial.print((kalAngleY) - 180,0);
Serial.println(" ");
}
if ( val == 'v')
{
Serial.println("RUSSIAN VODKA");
}
} */
if (round(kalAngleX) == 180)
{
digitalWrite(led, HIGH);
}
else
{
digitalWrite(led, LOW);
}
if (round(kalAngleY) == 180)
{
digitalWrite(red, HIGH);
}
else
{
digitalWrite(red, LOW);
}
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("X: ");
display.println(round(kalAngleX) - 180);
display.print("Y: ");
display.println(round(kalAngleY) - 180);
display.display();
delay (50);
}
void i2cWrite(uint8_t registerAddress, uint8_t data) {
Wire.beginTransmission(IMUAddress);
Wire.write(registerAddress);
Wire.write(data);
Wire.endTransmission();
}
uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {
uint8_t data[nbytes];
Wire.beginTransmission(IMUAddress);
Wire.write(registerAddress);
Wire.endTransmission(false); // Don't release the bus
Wire.requestFrom(IMUAddress, nbytes);
for (uint8_t i = 0; i < nbytes; i++)
data [i] = Wire.read();
return data;
}
doubleaccXangle;// Angle calculate using the accelerometer024doubleaccYangle;025doubletemp;026doublegyroXangle = 180;// Angle calculate using the gyro027doublegyroYangle = 180;028doublecompAngleX = 180;// Calculate the angle using a Kalman filter029doublecompAngleY = 180;030doublekalAngleX;// Calculate the angle using a Kalman filter031doublekalAngleY;занимает 2 байта, поменяй на int и проверь работу.
оптимизировать просто всего за 150р. это купить второй про мини.
1) Земенить все ардуиновские функции pinMode(), digitalWrite() на прямое управление портами через регистры.
2) Вместо объявления переменных с номерами пинов (int led, int red), которые занимают аж по два байта, написать через директиву #define.
3) Проверить тип каждой переменной, чтобы её размерность не была больше, чем требуется. Например значение переменной var не превысит 100, поэтому объявлять её int избыточно. Для этой переменной будет достаточно byte.
Думаю
uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {143uint8_t data[nbytes];из-за сломаного мозга вышло.
Pro Mini 168 стоит 80 руб., Pro Mini 328 - 100 руб. Оно действительно стоит того, чтобы из-за 20 рублей ломать голову?
Я бы предложил убрать строки 71-87 и сделать не 100 замеров, а 101, на последнем изменив делители с 10000 на 1000000 - отличие же только в них, если я правильно понимаю.
Спасибо парни за советы. У меня про мини 8герц 16кб.(самая бомжовая*). Я пробовал вырезать ВСЕ из кода! Добился компиляции когда размер скетча стал примерно 7кб... Короче выход только один: ждать про мини атмегу328. Весьма благодарен за разбор кода! Жду новую мини и не censored больше никому(включая себя) мозг.
Я по незнанке заказывал про мини для кучи. Параметры не смотрел и вообще не задумывался что она когда-либо пригодится. Теперь на фоксе. П.С. На стоимость платки не заострял внимание, на бабло censored, там копейки.
Так в чем проблема? 7 кб кода не влезает в 14 кб памяти?
Из wire можно убрать где то 1 кб написав свой аналог и библиотеку дисплея наверняка можно порезать. Из них полюбому можно убрать больше, чем из 150 строк скетча :) Я именно так и сделал когда пары кб не хватало.
Я как-то мимо темы прошел, а сам решал такое. Жрет дисплей. Адафутовская библиотека - ужОс! Она же буфер 1К отводит под дисплей (128х64).
Найдите удобную Вам библиотеку БЕЗ ЭТОГО ЧОРТОВОГО буфера. Я - не помогу, просто свои примитивы писал. Четко под задачу.
Хотябы все шрифты, кроме используемого, уберите из Ады. Адафпутовская библиотека - только "дразнилка" красивостями дисплея. Применять в проектах ее почти невозможно.
Вник в код: В программе выводятся симолы: 'X','Y',':',' ', и 10 цифр. А сакральные знания о том, как печатать еще две сотни знаков, Вы тащите в своей программе! Это лишние 1210 байт.
Ну там не только это. Для универсальности напихано, так сказать... Что в wire, что в графических. Под себя можно резануть неплохо, но придется таскать библиотеки эти свои постоянно со скетчем.