Выделение функций в отдельные файлы (.cpp и .h)

Есть готовый рабочий файл fanju.ino (декодирование сигнала датчика погодной станции). Компилируется без проблем. Хочу сделать свой проект метеостанции с применением функций из него. Попытался начать так:

  1. Создал свой пустой скетч (файл ws.ino)
  2. Скопировал полностью весь код из оригинального скетча. Проверил - скомпилировал свой - компилируется.
  3. Добавил в папку своего проекта файл fanju.cpp с текстом
#include "fanju.h"
  1. Добавил в папку своего проекта файл fanju.h с текстом
#ifndef FANJU_H
#define FANJU_H

#endif
  1. Проверил - ws.ino по прежнему компилируется.
  2. Вырезаю из ws.ino функцию и вставляю её в файл fanju.cpp, а в файл fanju.h строчу, и скетч перестаёт компилироваться.
    fanju.cpp:
#include "fanju.h"
void push(uint8_t v)
{
  buffer[widx++] = v;
  lvl++;
  if (widx == BUF_SIZE)
    widx = 0;
}

fanju.h:

#ifndef FANJU_H
#define FANJU_H

void push(uint8_t v)

#endif

Ошибки:
error: variable or field ‘push’ declared void
error: ‘uint8_t’ was not declared in this scope
и далее связанные…

Что я делаю не так? Как вынести функции из файла .ino в отдельные файлы? вроде всё по инструкциям, но не работает…

Видимо, читать не умеешь… Он же тебе говорит: error: ‘uint8_t’ was not declared in this scopeЯ, говорит, не знаю что это еще такое за uint8_t ? Самогон?

Забыл ;
В срр включи “Ардуино.х”.
Вообще, посмотри как люди делают в библиотеках.

Где точка с запятой?

Включите файл Arduino.h

По какой инструкции?

Добавил в .h

#ifndef FANJU_H
#define FANJU_H

void push(uint8_t v);
void isr();

#endif

Включил в .cpp

#include "fanju.h"
#include <Arduino.h>

void push(uint8_t v)
{
  buffer[widx++] = v;
  lvl++;
  if (widx == BUF_SIZE)
    widx = 0;
}

void isr()
{
  uint64_t cur = micros() / 100;
  push(cur - last);
  last = cur;
}

Проблема осталась. Чего-то ещё не хватает:

In file included from D:\ws\fanju.cpp:1:0:
D:\ws\fanju.h:4:11: error: variable or field ‘push’ declared void
void push(uint8_t v);
^~~~~~~
D:\ws\fanju.h:4:11: error: ‘uint8_t’ was not declared in this scope
D:\ws\fanju.cpp: In function ‘void push(uint8_t)’:
D:\ws\fanju.cpp:6:3: error: ‘buffer’ was not declared in this scope
buffer[widx++] = v;
^~~~~~
D:\ws\fanju.cpp:6:10: error: ‘widx’ was not declared in this scope
buffer[widx++] = v;
^~~~
D:\ws\fanju.cpp:7:3: error: ‘lvl’ was not declared in this scope
lvl++;
^~~
D:\ws\fanju.cpp:8:15: error: ‘BUF_SIZE’ was not declared in this scope
if (widx == BUF_SIZE)
^~~~~~~~
D:\ws\fanju.cpp:8:15: note: suggested alternative: ‘BUFSIZ’
if (widx == BUF_SIZE)
^~~~~~~~
BUFSIZ
D:\ws\fanju.cpp: In function ‘void isr()’:
D:\ws\fanju.cpp:15:14: error: ‘last’ was not declared in this scope
push(cur - last);
^~~~
D:\ws\fanju.cpp:15:14: note: suggested alternative: ‘labs’
push(cur - last);
^~~~
labs

exit status 1

Compilation error: variable or field ‘push’ declared void

и очень многого :slight_smile:

Я тут писал в другой теме вчера, хоть и по другому поводу: “функция - это отдельный мир”. К вам относится в полной мере.

Чтобы вы могли вынести функцию в отдельный файл - она не должна использовать никаких глобальных переменных, таких как у вас last buffer lvl и тд
Все переменные должны быть или локальными для функции или файла, или передаваться ей как параметры.

Смотрел тут
https://forum.amperka.ru/threads/%D0%9A%D0%B0%D0%BA-%D0%B2%D1%8B%D0%BD%D0%B5%D1%81%D1%82%D0%B8-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8-%D0%B2-%D0%BE%D1%82%D0%B4%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9-%D1%84%D0%B0%D0%B9%D0%BB.5206/
и тут

Да, про “;” просмотрел. Но про подключение Ардуино.аш там не сказано.
Делать библиотеку не вижу смысла, достаточно было бы в отдельные файлы вынести процедуры и функции, относящиеся к отдельной структурной части проекта.
Если укажете где правильная, подробная инструкция, буду премного благодарен.

начните с обдумывания последней фразы в сообщении 7

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

Она и не уйдет. Arduino.h нужно подключать в .h файле. Для начала. А затем разбираться, почему в .cpp файле вы используете переменные, которые там не объявлены

1 лайк

можно Arduino.h поставить первым в .cpp

Писец! Так надо ж было не только строки, а ещё и мозги включить!

Куда Вы там что включили? У Вас по-прежнему fanju.h компилируется без Arduino.h

Или Вставьте

#include <Arduino.h>

в “fanju.h” третьей строкой (и больше никуда). Или делайте так, чтобы везде Arduino.h включалась РАНЬШЕ, чем fanju.h

1 лайк

Можно по всякому, но правильнее будет таки в .h файле

Вот здесь.

1 лайк

Попробуйте в *.h вставить extern для переменных, используемых в основной программе.

Всем откликнувшимся спасибо.
Удаляюсь осмыслять, читать, переделывать.

Не знаю почему, но я стараюсь extern не использовать. Во всяком случае, свой код проектирую так, чтобы extern не понадобился. В чужом коде иногда приходится добавлять extern, чтобы не переписывать слишком много.

В целом, воспринимаю его как “костыль”, прибегать к которому недостойно “нормальных пацанов” :slight_smile:

Может @ЕвгенийП что-то скажет на эту тему…

Не понял, это как? Все функции и переменные в одном файле держите?

А попробуйте написать код для ББ с внешними библиотеками …

Нет, зачем? Просто почти не использую глобальных переменных и статических уровня файла. (уточнение - статические переменные использую, но стараюсь не обращаться к переменным одного файла из другого).

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