My C++ skills are rather amateurish, but I’m trying to write a library for a differential drive robotic platform. The library in question needs to utilise a PID library and a rotary encoder library.
I’d like to utilise “levels of abstraction” to do this, rather than just having a massive “sketch” as it makes things a lot easier to read, and to be honest, is the point of object orientated programming. I.e i can write a class to control the a dc motor and just use multiple instances for each side. (I apologise if I’ve got the terminology wrong).
Essentially I’m having trouble utilising the third party libraries within my library.
If i was to write a simple sketch that used the two third party libraries, it would look like this (paraphrasing) -
#include <Arduino.h>
#include <RotaryEncoder.h>
#include <PID_v1.h>
#include <L298N.h>
char A_IN1 = 8;
char A_IN2 = 9;
char A_EN = 17;
char PIN_IN1 = 4;
char PIN_IN2 = 5;
double Setpoint, Output;
double Input = 0;
double Kp=1.3, Ki=15, Kd=0.01;
RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
void checkPosition(){
//some code that increments the encoder value
}
void setup(){
attachInterrupt(digitalPinToInterrupt(PIN_IN1), checkPosition, CHANGE);
pinMode(PIN_IN1, INPUT);
attachInterrupt(digitalPinToInterrupt(PIN_IN2), checkPosition, CHANGE);
pinMode(PIN_IN2, INPUT);
Setpoint = 0;
myPID.SetSampleTime(20);
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0,255);
}
void loop(){
//loop code that uses PID to drive motors at appropriate speed etc etc
}
How does one go about implementing the two libraries into a custom library?
E.g two files L298N.cpp and L298N.h? Below is what I’ve tried, but no luck.
L298N.cpp
#include "Arduino.h"
#include "L298N.h"
#include <RotaryEncoder.h>
#include <PID_v1.h>
L298N::L298N(char IN1, char IN2, char EN, char A_INT1, char A_INT2){
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(EN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(A_INT1), checkPosition, CHANGE);
attachInterrupt(digitalPinToInterrupt(A_INT2), checkPosition, CHANGE);
pinMode(A_INT1, INPUT);
pinMode(A_INT2, INPUT);
RotaryEncoder encoder(A_INT1, A_INT2, RotaryEncoder::LatchMode::TWO03);
PID pid(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
pid.SetSampleTime(20);
pid.SetMode(AUTOMATIC);
pid.SetOutputLimits(0,255);
_IN1 = IN1;
_IN2 = IN2;
_EN = EN;
}
void L298N::checkPosition(){
encoder.tick(); // just call tick() to check the state.
}
double L298N::calculate_rpm(){
long new_position = encoder.getPosition();
long position_change;
double RPM;
if (new_position != old_position) {
tick_time = (millis() - last_time);
position_change = old_position - new_position;
RPM = 1 / ((double(tick_time / position_change) * 125)/1000/60); //10041 18538 = ticks per rev, 1 rev = 42.73cm
old_position = new_position;
last_time = millis();
}
else{
RPM = 0.0;
}
delay(20); // required for dagu as encoders are shit and only pulse 125 times per rev
return RPM;
}
void L298N::set_rpm(int rpm){
Setpoint = rpm;//covert_vel_rpm(vel);
Input = calculate_rpm();
pid.Compute();
if (Setpoint > 0.0){
forwards(char(Output));
}
else{
backwards(char(Output));
}
}
void L298N::forwards(char pwm){
digitalWrite(_IN1, HIGH);
digitalWrite(_IN2, LOW);
analogWrite(_EN, pwm);
return;
}
void L298N::backwards(char pwm){
digitalWrite(_IN1, LOW);
digitalWrite(_IN2, HIGH);
analogWrite(_EN, pwm);
return;
}
L298N.h
#ifndef L298N_h
#define L298N_h
#include "Arduino.h"
#include <RotaryEncoder.h>
#include <PID_v1.h>
class L298N
{
public:
L298N(char IN1, char IN2, char EN, char A_INT1, char A_INT2);
void set_rpm(int rpm);
private:
char _IN1, _IN2, _EN, _INT1, _INT2;
double last_time = millis();
double tick_time = 0;
long old_position = 0;
double Setpoint, Output;
double Input = 0;
double Kp=1.3, Ki=15, Kd=0.01;
RotaryEncoder encoder;//(char A_INT1, char A_INT2, RotaryEncoder::LatchMode::TWO03);
PID pid;//(double &Input, double &Output, double &Setpoint, double Kp, double Ki, double Kd, char DIRECT);
void checkPosition();
double calculate_rpm();
void forwards(char pwm);
void backwards(char pwm);
};
#endif
test.ino
#include <L298N.h>
#include <RotaryEncoder.h>
#include <PID_v1.h>
char A_IN1 = 8;
char A_IN2 = 9;
char A_EN = 17;
char A_INT1 = 3;
char A_INT2 = 4;
L298N left(A_IN1, A_IN2, A_EN, A_INT1, A_INT2);
void setup(){
}
void loop(){
left.set_rpm(20);
}
errors:
Arduino: 1.8.15 (Linux), Board: "Arduino Uno"
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.cpp: In constructor
'L298N::L298N(char, char, char, char, char)':
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.cpp:7:67: error: no
matching function for call to 'RotaryEncoder::RotaryEncoder()'
L298N::L298N(char IN1, char IN2, char EN, char A_INT1, char A_INT2)
^ In file included from
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.h:10:0,
from /home/ubuntu/Arduino/libraries/L298N_driver/L298N.cpp:3:
/home/ubuntu/Arduino/libraries/RotaryEncoder/src/RotaryEncoder.h:39:3:
note: candidate: RotaryEncoder::RotaryEncoder(int, int,
RotaryEncoder::LatchMode) RotaryEncoder(int pin1, int pin2,
LatchMode mode = LatchMode::FOUR0); ^~~~~~~~~~~~~
/home/ubuntu/Arduino/libraries/RotaryEncoder/src/RotaryEncoder.h:39:3:
note: candidate expects 3 arguments, 0 provided
/home/ubuntu/Arduino/libraries/RotaryEncoder/src/RotaryEncoder.h:23:7:
note: candidate: constexpr RotaryEncoder::RotaryEncoder(const
RotaryEncoder&) class RotaryEncoder
^~~~~~~~~~~~~ /home/ubuntu/Arduino/libraries/RotaryEncoder/src/RotaryEncoder.h:23:7:
note: candidate expects 1 argument, 0 provided
/home/ubuntu/Arduino/libraries/RotaryEncoder/src/RotaryEncoder.h:23:7:
note: candidate: constexpr
RotaryEncoder::RotaryEncoder(RotaryEncoder&&)
/home/ubuntu/Arduino/libraries/RotaryEncoder/src/RotaryEncoder.h:23:7:
note: candidate expects 1 argument, 0 provided
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.cpp:7:67: error: no
matching function for call to 'PID::PID()' L298N::L298N(char IN1,
char IN2, char EN, char A_INT1, char A_INT2)
^ In file included from
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.h:11:0,
from /home/ubuntu/Arduino/libraries/L298N_driver/L298N.cpp:3:
/home/ubuntu/Arduino/libraries/PID/PID_v1.h:24:5: note: candidate:
PID::PID(double*, double*, double*, double, double, double, int)
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and
^~~ /home/ubuntu/Arduino/libraries/PID/PID_v1.h:24:5: note: candidate expects 7 arguments, 0 provided
/home/ubuntu/Arduino/libraries/PID/PID_v1.h:20:5: note: candidate:
PID::PID(double*, double*, double*, double, double, double, int, int)
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and
^~~ /home/ubuntu/Arduino/libraries/PID/PID_v1.h:20:5: note: candidate expects 8 arguments, 0 provided
/home/ubuntu/Arduino/libraries/PID/PID_v1.h:5:7: note: candidate:
constexpr PID::PID(const PID&) class PID
^~~ /home/ubuntu/Arduino/libraries/PID/PID_v1.h:5:7: note: candidate expects 1 argument, 0 provided
/home/ubuntu/Arduino/libraries/PID/PID_v1.h:5:7: note: candidate:
constexpr PID::PID(PID&&)
/home/ubuntu/Arduino/libraries/PID/PID_v1.h:5:7: note: candidate
expects 1 argument, 0 provided
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.cpp:13:70: error:
invalid use of non-static member function 'void
L298N::checkPosition()'
attachInterrupt(digitalPinToInterrupt(A_INT1), checkPosition, CHANGE);
^ In file included from
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.cpp:3:0:
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.h:33:7: note:
declared here void checkPosition();
^~~~~~~~~~~~~ /home/ubuntu/Arduino/libraries/L298N_driver/L298N.cpp:14:70: error:
invalid use of non-static member function 'void
L298N::checkPosition()'
attachInterrupt(digitalPinToInterrupt(A_INT2), checkPosition, CHANGE);
^ In file included from
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.cpp:3:0:
/home/ubuntu/Arduino/libraries/L298N_driver/L298N.h:33:7: note:
declared here void checkPosition();
^~~~~~~~~~~~~ exit status 1 Error compiling for board Arduino Uno.
This report would have more information with "Show verbose output
during compilation" option enabled in File -> Preferences.
Any help of how to do this properly would be greatly appreciated. It’s just using a class within a class (terminology might be wrong) but this is quite trivial to do in Python.
Cheers!
You have several problems.
You said
PID and RotaryEncoder libraries are standard arduino libraries
That's wrong, those libraries are not standard, you have to install them using the Library Manager (otherwise it would have compiled).
Those are:
- RotaryEncoder, by Mathias Hertel
http://www.mathertel.de/Arduino/RotaryEncoderLibrary.aspx
- Arduino PID Library, by Brett Beauregard
https://github.com/br3ttb/Arduino-PID-Library
Local includes should use quotes, system/external includes must use brackets:
#include "L298N.h"
#include <RotaryEncoder.h>
RotaryEncoder does not have a default constructor, so you either initialize it using the initializer list or just remove the member variable.
PID doesn't have a default constructor either.
You cannot use a class member function as an interrupt handler. This:
attachInterrupt(digitalPinToInterrupt(A_INT1), checkPosition, CHANGE);
will never work. You may have to use a singleton or similar:
L298N left(A_IN1, A_IN2, A_EN, A_INT1, A_INT2);
// code
void int_checkPosition() {
left.checkPosition()
}
// more code
// this may go in setup()
attachInterrupt(digitalPinToInterrupt(A_INT2), checkPosition, CHANGE);
I changed the code in the constructor to make it look like this and compiles.
// encoder and pid initialized properly
L298N::L298N(byte IN1, byte IN2, byte mEN, byte A_INT1, byte A_INT2)
: encoder((int)A_INT1, (int)A_INT2, RotaryEncoder::LatchMode::TWO03)
, pid(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT)
{
piL298N::L298N(byte IN1, byte IN2, byte EN, byte A_INT1, byte A_INT2)
: encoder((int)A_INT1, (int)A_INT2, RotaryEncoder::LatchMode::TWO03)
, pid(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT)
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(EN, OUTPUT);
// this doesn't work (use the recommendation above)
//attachInterrupt(digitalPinToInterrupt(A_INT1), checkPosition, CHANGE);
//attachInterrupt(digitalPinToInterrupt(A_INT2), checkPosition, CHANGE);
pinMode(A_INT1, INPUT);
pinMode(A_INT2, INPUT);
// you don't need this. in fact, it wasn't going to work
// because you needed it to be a class member.
//RotaryEncoder encoder((int)A_INT1, (int)A_INT2, RotaryEncoder::LatchMode::TWO03);
//PID pid(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
pid.SetSampleTime(20);
pid.SetMode(AUTOMATIC);
pid.SetOutputLimits(0,255);
_IN1 = IN1;
_IN2 = IN2;
_EN = EN;
}
It is up to you to fix the issue with the interrupt handler.
i think I understand what are you asking. Arduino (and many other IDE) has two different types o library
1) Local libraries
2) External Libraries
Local Libraries are those that you include by the syntaxis:
#include "Your_library.h"
External Libraries are those with the syntaxis:
#include <Your_library.h>
The difference between them is that the Local Libraries are supposed to be in the same folder of the proyect, it means that if you have a folder
Arduino/My_proyect/My_Proyect.ino
the library should be in
Arduino/My_proyect/Your_library.h
Instead, external Libraries are in the Arduino "libraries" folder
Arduino/libraries/Your_library/Your_library.h
Maybe the problem with your code is that you are using the bad type of syntaxis for the library, try to put all the libraries you want to use (.h and .cpp) in the same file and create a folder in the arduino "libraries" folder, then, include your librarys using the external syntaxis
#include <Folder_name.h>
This should work!
I'm trying to compile my code based on SinricPro but I'm getting a huge error.
Libraries:
Wifi - 1.2.7
ArduinoJson - 6.12.0
SinricPro - 2.4.0
WebSockets - 2.2.0
Arduino board:
Node MCU with ESP8266MOD
The error:
Arduino: 1.8.13 (Windows Store 1.8.39.0) (Windows 10), Board: "NodeMCU 0.9 (ESP-12 Module), 80 MHz, 115200, 4M (3M SPIFFS)"
In file included from C:\Users\amng8\Documents\ArduinoProjects\Sinric\Sinric.ino:13:0:
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h:122:5: error: 'vector' in namespace 'std' does not name a type
std::vector<SinricProDeviceInterface*> devices;
^
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h: In member function 'SinricProDeviceInterface* SinricProClass::getDevice(String)':
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h:139:23: error: 'devices' was not declared in this scope
for (auto& device : devices) {
^
In file included from C:\Users\amng8\Documents\ArduinoProjects\Sinric\Sinric.ino:13:0:
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h: In member function 'DeviceType& SinricProClass::add(const char*, long unsigned int)':
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h:211:3: error: 'devices' was not declared in this scope
devices.push_back(newDevice);
^
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h: In member function 'void SinricProClass::add(SinricProDeviceInterface*)':
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h:219:3: error: 'devices' was not declared in this scope
devices.push_back(newDevice);
^
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h: In member function 'void SinricProClass::add(SinricProDeviceInterface&)':
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h:226:3: error: 'devices' was not declared in this scope
devices.push_back(&newDevice);
^
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h: In member function 'void SinricProClass::handleRequest(ArduinoJson6120_000001::DynamicJsonDocument&, interface_t)':
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h:305:23: error: 'devices' was not declared in this scope
for (auto& device : devices) {
^
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h: In member function 'void SinricProClass::connect()':
C:\Users\amng8\Documents\Arduino\libraries\SinricPro\src/SinricPro.h:391:23: error: 'devices' was not declared in this scope
for (auto& device : devices) {
^
exit status 1
Error compiling for board NodeMCU 0.9 (ESP-12 Module).
My code:
// Uncomment the following line to enable serial debug output
#define ENABLE_DEBUG
#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "SinricPro.h"
#include "SinricProGarageDoor.h"
#include "SinricProSwitch.h"
#define WIFI_SSID "DUMMY"
#define WIFI_PASS "DUMMY"
#define APP_KEY "DUMMY"
#define APP_SECRET "DUMMY"
#define GARAGEDOOR_ID "DUMMY"
#define SWITCH_LIGHTS_ID "DUMMY"
#define BAUD_RATE 9600
#define STATUS_LED D0
#define RELAY_1 D4
#define RELAY_2 D1
#define RELAY_3 D2
#define RELAY_4 D3
bool myPowerState = false;
bool onDoorState(const String& deviceId, bool &doorState) {
digitalWrite(RELAY_1, LOW);
delay(500);
digitalWrite(RELAY_1, HIGH);
Serial.printf("Garagedoor is %s now.\r\n", doorState?"closed":"open");
return true;
}
bool onPowerState(const String &deviceId, bool &state) {
Serial.printf("Device %s turned %s (via SinricPro) \r\n", deviceId.c_str(), state?"on":"off");
myPowerState = state;
digitalWrite(RELAY_2, myPowerState?HIGH:LOW);
return true; // request handled properly
}
void setupWiFi() {
Serial.printf("\r\n[Wifi]: Connecting");
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.printf(".");
digitalWrite(STATUS_LED, HIGH);
delay(500);
digitalWrite(STATUS_LED, LOW);
delay(500);
}
IPAddress localIP = WiFi.localIP();
Serial.printf("connected!\r\n[WiFi]: IP-Address is %d.%d.%d.%d\r\n", localIP[0], localIP[1], localIP[2], localIP[3]);
digitalWrite(STATUS_LED, HIGH);
}
void setupSinricPro() {
SinricProGarageDoor &myGarageDoor = SinricPro[GARAGEDOOR_ID];
myGarageDoor.onDoorState(onDoorState);
SinricProSwitch &mySwitch = SinricPro[SWITCH_LIGHTS_ID];
mySwitch.onPowerState(onPowerState);
// setup SinricPro
SinricPro.onConnected([](){ Serial.printf("Connected to SinricPro\r\n"); });
SinricPro.onDisconnected([](){ Serial.printf("Disconnected from SinricPro\r\n"); });
SinricPro.begin(APP_KEY, APP_SECRET);
}
void setup() {
pinMode(STATUS_LED, OUTPUT);
pinMode(RELAY_1, OUTPUT);
pinMode(RELAY_2, OUTPUT);
pinMode(RELAY_3, OUTPUT);
pinMode(RELAY_4, OUTPUT);
digitalWrite(STATUS_LED, LOW);
digitalWrite(RELAY_1, HIGH);
digitalWrite(RELAY_2, HIGH);
digitalWrite(RELAY_3, HIGH);
digitalWrite(RELAY_4, HIGH);
Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
setupWiFi();
setupSinricPro();
}
void loop() {
SinricPro.handle();
}
This error seems something from the SinricPro libraries and I can't seem to understand why is this error occurring.
GitHub issue
I'm currently trying to program my M5Stack with an ESP32 chip in it. I downloaded (or atleast I thought) all of the dependencies needed to upload to the board, but I can't even get my program to compile. I downloaded the ESP32 throught the board manager, I followed the M5Stack tutorial on their website and seem to be finding errors in thheir library itself. I'm not sure how to fix, below is my code and below that are the error messages im getting.
#include <M5Stack.h>
#include <Wire.h>
#define SPEAKER_PIN 25
#include "config.h"
AdafruitIO_Feed *voltage1 = io.feed("V1");
AdafruitIO_Feed *voltage2 = io.feed("V2");
AdafruitIO_Feed *curr = io.feed("Current");
void setup() {
// put your setup code here, to run once:
M5.begin(true, true, true, false);
Serial.begin(115200);
dacWrite(25,0);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(5);
// wait for serial monitor to open
while(! Serial);
Serial.print("Connecting to Adafruit IO");
// connect to io.adafruit.com
io.connect();
// wait for a connection
while(io.status() < AIO_CONNECTED) {
Serial.print(".");
delay(500);
}
// we are connected
Serial.println();
Serial.println(io.statusText());
// ads.getAddr_ADS1100(ADS1100_DEFAULT_ADDRESS);
// ads.setGain(GAIN_ONE);
// ads.setMode(MODE_CONTIN);
// ads.setRate(RATE_32);
// ads.setOSMode(OSMODE_SINGLE);
// ads.begin();
}
void loop() {
io.run();
// put your main code here, to run repeatedly:
float v1 = (float)analogRead(36) / 4096 * 17.4 * 0.975;
float v2 = (float)analogRead(35) / 4096 * 17.4 * 0.975;
float current = (float)analogRead(5);
Serial.print("v1: ");
Serial.print(v1);
Serial.println("V");
Serial.print("v2: ");
Serial.print(v2);
Serial.println("V");
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(10, 10);
M5.Lcd.print("V1: ");
M5.Lcd.print(v1);
M5.Lcd.print("V");
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(10, 70);
M5.Lcd.print("V2: ");
M5.Lcd.print(v2);
M5.Lcd.print("V");
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(10, 140);
M5.Lcd.print("Current: ");
M5.Lcd.print(current);
M5.Lcd.print("A");
delay(500);
M5.Lcd.setCursor(10, 10);
M5.Lcd.setTextColor(BLACK);
M5.Lcd.print("V1: ");
M5.Lcd.print(v1);
M5.Lcd.print("V");
M5.Lcd.setCursor(10, 70);
M5.Lcd.setTextColor(BLACK);
M5.Lcd.print("V2: ");
M5.Lcd.print(v2);
M5.Lcd.print("V");
M5.Lcd.setTextColor(BLACK);
M5.Lcd.setCursor(10, 140);
M5.Lcd.print("Current: ");
M5.Lcd.print(current);
M5.Lcd.print("A");
Serial.print("sending v1-> ");
Serial.println(v1);
voltage1->save(v1);
Serial.print("sending v2-> ");
Serial.println(v2);
voltage2->save(v2);
Serial.print("sending Current-> ");
Serial.println(current);
curr->save(current);
}
Error output:
Arduino: 1.8.12 (Windows 10), Board: "M5Stack-Core-ESP32, QIO, 80MHz, Default, 921600, None"
C:\Users\graff\OneDrive\Documents\Arduino\libraries\M5Stack\src\M5Display.cpp: In member function 'void M5Display::drawPngUrl(const char*, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, double, uint8_t)':
C:\Users\graff\OneDrive\Documents\Arduino\libraries\M5Stack\src\M5Display.cpp:543:3: error: 'HTTPClient' was not declared in this scope
HTTPClient http;
^
C:\Users\graff\OneDrive\Documents\Arduino\libraries\M5Stack\src\M5Display.cpp:545:7: error: 'WiFi' was not declared in this scope
if (WiFi.status() != WL_CONNECTED) {
^
C:\Users\graff\OneDrive\Documents\Arduino\libraries\M5Stack\src\M5Display.cpp:545:24: error: 'WL_CONNECTED' was not declared in this scope
if (WiFi.status() != WL_CONNECTED) {
^
C:\Users\graff\OneDrive\Documents\Arduino\libraries\M5Stack\src\M5Display.cpp:550:3: error: 'http' was not declared in this scope
http.begin(url);
^
C:\Users\graff\OneDrive\Documents\Arduino\libraries\M5Stack\src\M5Display.cpp:553:19: error: 'HTTP_CODE_OK' was not declared in this scope
if (httpCode != HTTP_CODE_OK) {
^
C:\Users\graff\OneDrive\Documents\Arduino\libraries\M5Stack\src\M5Display.cpp:559:3: error: 'WiFiClient' was not declared in this scope
WiFiClient *stream = http.getStreamPtr();
^
C:\Users\graff\OneDrive\Documents\Arduino\libraries\M5Stack\src\M5Display.cpp:559:15: error: 'stream' was not declared in this scope
WiFiClient *stream = http.getStreamPtr();
^
Multiple libraries were found for "WiFi.h"
Used: C:\Users\graff\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WiFi
Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
Not used: C:\Users\graff\OneDrive\Documents\Arduino\libraries\WiFi
Multiple libraries were found for "SD.h"
Used: C:\Users\graff\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\SD
Not used: C:\Program Files (x86)\Arduino\libraries\SD
Not used: C:\Users\graff\OneDrive\Documents\Arduino\libraries\SD
exit status 1
Error compiling for board M5Stack-Core-ESP32.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
First of all you should do what your compiler wants:
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
This gives more details and if the solution is not working edit your question and replace the compiler output with the detailed Info.Include the missinglibs manually in your program
#include <WiFi.h>
#include <SD.h>
#include <M5Stack.h>
#include <Wire.h>
and checkthe dependencies you have in
#include "config.h"
as I could not compile due to missing file
I'm totally new to C/C++. I've done some higher languages like Java and C# but that's something else I must say. I'm trying to build a timer module for the Arduino so that I can easily queue work that has to be executed after a certain amount of time without the use of delay(). I would like to create it as intuitively as possible so that I can easily re-use it.
So far I've tried a lot of different approaches. What I did is mostly read tutorials on how to achieve a certain thing in C/C++ and created my little project out of that.
Main .ino file:
#include "Timer.h"
Timer timer;
void setup()
{
// Init the timer
timer.init();
pinMode(13, OUTPUT);
// Define the state
int state = 1;
// Create the action
TimerAction action;
action.create(1000, &timerElapsed, 1 -1);
action.state = &state;
}
void loop()
{
timer.run();
}
void timerElapsed(TimerAction action) {
int *state = (int*)action.state;
if (state == 0) {
digitalWrite(13, HIGH);
*state = 1;
}
else
{
digitalWrite(13, LOW);
*state = 0;
}
}
It's very simple. I'm trying to blink the onboard led as a proof of concept.
This is the Timer.h file:
#ifndef _TIMER_h
#define _TIMER_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "arduino.h"
#else
#include "WProgram.h"
#endif
struct Timer {
TimerAction* actions;
uint8_t size;
void init();
void queue(TimerAction action);
void dequeue(TimerAction action);
void dequeueIdx(int idx);
void run();
};
struct TimerAction {
// Sets whether to repeat the action
uint8_t repetitive;
// Sets how many times to repeat the action, -1 for infinite
// Will only be used when repetitive == 1
long finite;
void (*callback)(TimerAction sender);
void *state;
unsigned long last;
unsigned long interval;
void create(long interval, void(*callback)(TimerAction sender), uint8_t repetitive = 0U, long finite = -1L);
};
#endif
This is the Timer.ino file:
#include "Timer.h"
void Timer::init() {
size = 0;
actions = new TimerAction[10];
}
void Timer::queue(TimerAction action) {
action.last = millis();
actions[size - 1] = action;
size++;
}
void Timer::dequeue(TimerAction action) {
for (int i = 0; i < size; i++)
if (&(actions[i]) == &action) {
memmove(actions + i, actions + i + 1, (size - (i + 1)) * sizeof(TimerAction));
break;
}
}
void Timer::dequeueIdx(int idx) {
memmove(actions + idx, actions + idx + 1, (size - (idx + 1)) * sizeof(TimerAction));
}
void Timer::run() {
for (int i = 0; i < size; i++)
if ((actions[i].last + actions[i].interval) >= millis()) {
TimerAction action = actions[i];
action.callback(action);
if (action.repetitive == 1) {
if (action.finite > 0)
action.finite--;
else
if (action.finite == 0)
dequeueIdx(i);
}
else
dequeueIdx(i);
}
}
void TimerAction::create(long _interval, void(*_callback)(TimerAction sender),
uint8_t _repetitive = 0U, long _finite = -1L) {
interval = _interval;
callback = _callback;
repetitive = _repetitive;
finite = _finite;
}
These are the errors the compiler spewed out:
Arduino: 1.6.1 (Windows 8.1), Board: "Arduino Uno"
In file included from Stoplicht.ino:1:0:
Timer.h:13:2: error: 'TimerAction' does not name a type
TimerAction* actions;
^
Timer.h:17:13: error: 'TimerAction' has not been declared
void queue(TimerAction action);
^
Timer.h:18:15: error: 'TimerAction' has not been declared
void dequeue(TimerAction action);
^
Timer.ino: In member function 'void Timer::init()':
Timer.ino:5:2: error: 'actions' was not declared in this scope
Timer.ino: At global scope:
Timer.ino:8:6: error: prototype for 'void Timer::queue(TimerAction)' does not match any in class 'Timer'
In file included from Stoplicht.ino:1:0:
Timer.h:17:7: error: candidate is: void Timer::queue(int)
void queue(TimerAction action);
^
Timer.ino:15:6: error: prototype for 'void Timer::dequeue(TimerAction)' does not match any in class 'Timer'
In file included from Stoplicht.ino:1:0:
Timer.h:18:7: error: candidate is: void Timer::dequeue(int)
void dequeue(TimerAction action);
^
Timer.ino: In member function 'void Timer::dequeueIdx(int)':
Timer.ino:24:10: error: 'actions' was not declared in this scope
Timer.ino: In member function 'void Timer::run()':
Timer.ino:29:8: error: 'actions' was not declared in this scope
Timer.ino: At global scope:
Timer.ino:45:52: error: default argument given for parameter 3 of 'void TimerAction::create(long int, void (*)(TimerAction), uint8_t, long int)' [-fpermissive]
In file included from Stoplicht.ino:1:0:
Timer.h:36:7: error: after previous specification in 'void TimerAction::create(long int, void (*)(TimerAction), uint8_t, long int)' [-fpermissive]
void create(long interval, void(*callback)(TimerAction sender), uint8_t repetitive = 0U, long finite = -1L);
^
Timer.ino:45:52: error: default argument given for parameter 4 of 'void TimerAction::create(long int, void (*)(TimerAction), uint8_t, long int)' [-fpermissive]
In file included from Stoplicht.ino:1:0:
Timer.h:36:7: error: after previous specification in 'void TimerAction::create(long int, void (*)(TimerAction), uint8_t, long int)' [-fpermissive]
void create(long interval, void(*callback)(TimerAction sender), uint8_t repetitive = 0U, long finite = -1L);
^
Let me explain why I'm using Array over a std::vector. My chain of thought was this: the Arduino is quite weak and actions is going to be accessed a lot. So I thought it's a bit more work to implement it initially but it will make sure the timer doesn't use too much of the Arduino's resources.
I've tried a lot of things but I don't really understand where the problem lies. So that's why I'm asking an expert to look at my code and maybe put me on the right track.
In Timer.h you have:
TimerAction* actions;
At the point in time that the compiler sees that line of code it has not seen what a TimerAction is. As such it does not know what the type is and is giving you an error. What you need to do is forward declare TimerAction before Timer so the compiler knows what it is doing.
#ifndef _TIMER_h
#define _TIMER_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "arduino.h"
#else
#include "WProgram.h"
#endif
struct TimerAction;
struct Timer {
//...