Большой размер скетча. Как оптимизировать код.

IZVERG18
Offline
Зарегистрирован: 01.03.2017

После компиляции скетч весит 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;
}

 

mrGoReC
Offline
Зарегистрирован: 16.06.2015
double accXangle; // Angle calculate using the accelerometer
024 double accYangle;
025 double temp;
026 double gyroXangle = 180; // Angle calculate using the gyro
027 double gyroYangle = 180;
028 double compAngleX = 180; // Calculate the angle using a Kalman filter
029 double compAngleY = 180;
030 double kalAngleX; // Calculate the angle using a Kalman filter
031

double kalAngleY;

занимает 2 байта, поменяй на int и проверь работу.

 

arDubino
Offline
Зарегистрирован: 12.01.2017

оптимизировать просто всего за 150р. это купить второй про мини.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

1) Земенить все ардуиновские функции pinMode(), digitalWrite() на прямое управление портами через регистры.

2) Вместо объявления переменных с номерами пинов (int led, int red), которые занимают аж по два байта, написать через директиву #define.

3) Проверить тип каждой переменной, чтобы её размерность не была больше, чем требуется. Например значение переменной var не превысит 100, поэтому объявлять её int избыточно. Для этой переменной будет достаточно byte.

Logik
Offline
Зарегистрирован: 05.08.2014

Думаю

  uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {
143   uint8_t data[nbytes];

из-за сломаного мозга вышло.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Pro Mini 168 стоит 80 руб., Pro Mini 328 - 100 руб. Оно действительно стоит того, чтобы из-за 20 рублей ломать голову?

sadman41
Offline
Зарегистрирован: 19.10.2016

Я бы предложил убрать строки 71-87 и сделать не 100 замеров, а 101, на последнем изменив делители с 10000 на 1000000 - отличие же только в них, если я правильно понимаю.

IZVERG18
Offline
Зарегистрирован: 01.03.2017

Спасибо парни за советы. У меня про мини 8герц 16кб.(самая бомжовая*). Я пробовал вырезать ВСЕ из кода! Добился компиляции когда размер скетча стал примерно 7кб... Короче выход только один: ждать про мини атмегу328. Весьма благодарен за разбор кода! Жду новую мини и не censored больше никому(включая себя) мозг.

Я по незнанке заказывал про мини для кучи. Параметры не смотрел и вообще не задумывался что она когда-либо пригодится. Теперь на фоксе.     П.С. На стоимость платки не заострял внимание, на бабло censored, там копейки.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Так в чем проблема? 7 кб кода не влезает в 14 кб памяти?

Morroc
Offline
Зарегистрирован: 24.10.2016

Из wire можно убрать где то 1 кб написав свой аналог и библиотеку дисплея наверняка можно порезать. Из них полюбому можно убрать больше, чем из 150 строк скетча :) Я именно так и сделал когда пары кб не хватало.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Я как-то мимо темы прошел, а сам решал такое. Жрет дисплей. Адафутовская библиотека - ужОс! Она же буфер 1К отводит под дисплей (128х64).

Найдите удобную Вам библиотеку БЕЗ ЭТОГО ЧОРТОВОГО буфера. Я - не помогу, просто свои примитивы писал. Четко под задачу.

Хотябы все шрифты, кроме используемого, уберите из Ады. Адафпутовская библиотека - только "дразнилка" красивостями дисплея. Применять в проектах ее почти невозможно.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Вник в код: В программе выводятся симолы: 'X','Y',':',' ', и 10 цифр. А сакральные знания о том, как печатать еще две сотни знаков, Вы тащите в своей программе! Это лишние 1210 байт.

Morroc
Offline
Зарегистрирован: 24.10.2016

Ну там не только это. Для универсальности напихано, так сказать... Что в wire, что в графических. Под себя можно резануть неплохо, но придется таскать библиотеки эти свои постоянно со скетчем.