Неприятный косяк в ИДЕ v1.6.4

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Компилял вот такой

#include "arhat.h"
#include "tsc.h"

#define pinRed          pin9    // нога со светодиодом R для плавного управления яркостью
#define pinGreen        pin4    // нога со светодиодом G для плавного управления яркостью
#define pinBlue         pin10   // нога со светодиодом B для плавного управления яркостью

#define WAIT_STEP       29      // тиков, 30 миллисекунд на 1 шаг изменения яркости
#define WAIT_CYCLE      156     // .., 160 миллисекунд паузы между повторением

#define WAIT_ON         98      // .., 100 мсек интервал включение контрольного светодиода (pinLed = 13)
#define WAIT_OFF        878     // .., 900 мсек интервал выключения контрольного светодиода

#define MAX_STEPS   4
#define MAX_HEARTS  3

uint32_t blinkWait;             // текущий интервал ожидания. WAIT_ON или WAIT_OFF могут отличаться!
uint8_t  blinkState;            // текущее состояние светодиода. НЕЛЬЗЯ прочитать через digitalRead() !!!

uint8_t starts[] = {10,230,20,220,10};
uint8_t steps[] = {20,15,15,10};

// ЭТО ОПРЕДЕЛЕНИЕ ТИПА НЕ РАБОТАЕТ В ИДЕ !!!
extern "C" {
  typedef struct {
    uint8_t  state;
    uint8_t  light;
  } Hearts_Data;
}

Hearts_Data heartsData[MAX_HEARTS] = {{ 0, 0}, {0, 0}, {0, 0}};

TSC_Simple      hearts[MAX_HEARTS] = {
/*   start,   command, timeout */
   {     0, doHeartRed,   0 }
  ,{  5000, doHeartGreen, 0 }
  ,{     0,      0,       0 }
};

void doHeart( Hearts_Data * t) { t++; }
/*
void doHeart( Hearts_Data * cur )
{
  uint8_t curMax  = starts[cur->state];
  uint8_t nextMax = starts[cur->state + 1];

  if( nextMax > curMax ){                               // яркость - увеличиваем?
    cur->light += steps[cur->state];
    if( cur->light >= nextMax ){                        // . дошли до максиума яркости стадии?
      ++(cur->state);                                   // .. переходим на след. стадию.
    }
  } else {
    cur->light -= steps[cur->state];
    if( cur->light <= nextMax ){                        // . уменьшаем текущую яркость. Миниум?
      ++cur->state;                                     // .. переходим на след. стадию.
    }
  }
  if( cur->state >= MAX_STEPS ){
    cur->state = 0;                                     // стадии кончились? Всё с начала.
  };
}
*/
uint8_t doHeartRed()
{
  doHeart(&heartsData[0]);
  analogWrite(pinRed, heartsData[0].light);
  return 0;
}

uint8_t doHeartGreen()
{
  doHeart(&heartsData[1]);
  if( ! hearts[2].command ){
    hearts[2].command = doHeartBlue;
    hearts[2].timeout = 3000;
    hearts[2].started_at = tsc_getTime();
  }
  analogWrite(pinGreen, heartsData[1].light);
  return 0;
}

uint8_t doHeartBlue()
{
  doHeart(&heartsData[2]);
  analogWrite(pinBlue, heartsData[2].light);

  if( hearts[0].command && heartsData[2].state == 3 ){
    hearts[0].command = 0;
  } else {
    hearts[0].command = doHeartRed;
  }
  return 0;
}

void setup() {
  pinMode(pinLed, OUTPUT);      // контрольная 13 нога (встроенный светодиод)

  pwmSet(pinRed);               // включаем 4-ю ногу в режим ШИМ (PWM) и на выход
  pwmSet(pinBlue);              // включаем 10-ю ногу в режим ШИМ (PWM) и на выход
  pwmSet(pinGreen);             // включаем 9-ю ногу в режим ШИМ (PWM) и на выход

  // начальные установки КА: всё в нули, поставят сами при первом вызове
  blinkWait = blinkState = 0;
}

void loop() {
  // пример КА, реализуемый непосредственно внутри вызова макроса:
  everyOVF(blinkWait,
  {
    if( blinkState == 0 ) { blinkState = 1; blinkWait = WAIT_ON; }
    else                  { blinkState = 0; blinkWait = WAIT_OFF; }
    digitalWrite(pinLed, blinkState);
  });

  // Запускаем все КА:
  for( int i=0; i<MAX_HEARTS; i++)
    tsc_run( &hearts[i] );

}

скетч и обнаружил косяк, связанный в предобработкой исходного файла в ИДЕ, а именно:

ИДЕ предобрабатывая скетч, выносит в его начало все определения функций из скетча. Вынос производится куда-то в начало, после операторов препроцессора (#define, #include), что приводит к проблеме невозможности вставки определений типов непосредственно в скетч, конкретно в нем - строки 023-029.

В данном случае, функция doHeart() использует определение типа в своем параметре и согласно правилам объявлена после определения типа Hearts_Data .. однако, из-за выноса её объявления в начало скетча и ДО определения типа возникает ошибка компилятора: тип Hearts_Data не определен в скетче... ошибка возникает на строке кода, не имеющей отношения к скетчу, что существенно затрудняет её поиск.

Решение: выносить все определения типов (насчет классов не знаю, не проверял) из скетча в отдельный *.h файл и включать его в скетч типовым образом. Что не есть удобно..

P.S. Может такое поведение где-то и описано, не искал и не встречал .. если нет и это ошибка - отправьте авторам плиз..

Клапауций 070
Offline
Зарегистрирован: 26.09.2015

Arhat109-2 пишет:

P.S. Может такое поведение где-то и описано, не искал и не встречал .. если нет и это ошибка - отправьте авторам плиз..

да - сделайте кто-нибудь что-нибудь, сил нет терпеть, приходится версию arduino-1.6.5-r5 юзать.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

А в ней это исправлено, где почитать можно?

Клапауций 070
Offline
Зарегистрирован: 26.09.2015

Arhat109-2 пишет:

А в ней это исправлено, где почитать можно?

да нигде, скорее всего та же песня будет

попробуй сам - скачай в зипе новую версию и расскажи нам.

версия в зипе никуда в реестр не прописывается и ничего тебе не сломает.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Да мне-то нафига? Я ваще ИДЕ не пользую уже. Все как надо работает. Это просто пример к либе, вот и решил проверить как оно в ИДЕ .. 6 часов убил пока доперло.

Клапауций 070
Offline
Зарегистрирован: 26.09.2015

Arhat109-2 пишет:

Я ваще ИДЕ не пользую уже. Все как надо работает.

ну, ок - поделись с народом, чем дуину пользуешь.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

kwrite, gedit + bash .. делов-то. :)