Dominik Bartsch 2 years ago
parent
commit
50e714e5f8

+ 1
- 0
.gitignore View File

.pio .pio
.vscode .vscode
compress compress
data_gz
platformio.ini platformio.ini
include/wifi_credentials.h include/wifi_credentials.h
include/*.gz.h include/*.gz.h

+ 2
- 1
.vscode/settings.json View File

"streambuf": "cpp", "streambuf": "cpp",
"cinttypes": "cpp", "cinttypes": "cpp",
"typeinfo": "cpp" "typeinfo": "cpp"
}
},
"python.pythonPath": "C:\\Users\\simon\\AppData\\Local\\Programs\\Python\\Python37\\python.exe"
} }

+ 38
- 0
create_gz_c_arr.py View File

#!/usr/bin/python3

import os, gzip
# https://www.mischianti.org/2020/10/26/web-server-with-esp8266-and-esp32-byte-array-gzipped-pages-and-spiffs-2/

def convert_to_gzip(src, out, f):
input_file = f'{src}{f}'
output_file = f'{out}{f}.gz.h'
output_charp = f'{f.replace(".", "_")}_gz'

top = ''
with open(input_file, 'rb') as f_in:
gz = gzip.compress(f_in.read())
gzlen = len(gz)

top += f'// filename: {f}.gz.h\n'
top += f'#define {output_charp}_len {gzlen}\n'
top += f'const char {output_charp}[] = '
top += '{'

with open(output_file, 'wb') as f_out:
for i, b in enumerate(gz):
if not i%10:
top += '\n '
top += f'0x{b:02X}, '
top = top[:-2]
top += '};'
f_out.write(top.encode(encoding='utf-8'))


src='data/'
out='compress/'

if not 'compress' in os.listdir():
os.mkdir('compress')

for f in os.listdir(src):
convert_to_gzip(src, out, f)

+ 9
- 32
create_gz_files.py View File

#!/usr/bin/python3 #!/usr/bin/python3


import os, gzip import os, gzip
# https://www.mischianti.org/2020/10/26/web-server-with-esp8266-and-esp32-byte-array-gzipped-pages-and-spiffs-2/
# https://stackoverflow.com/questions/8156707/gzip-a-file-in-python


def convert_to_gzip(src, out, f):
input_file = f'{src}{f}'
output_file = f'{out}{f}.gz.h'
output_charp = f'{f.replace(".", "_")}_gz'
src_dir='data'
out_dir='data_gz'


top = ''
with open(input_file, 'rb') as f_in:
gz = gzip.compress(f_in.read())
gzlen = len(gz)
if not 'data_gz' in os.listdir():
os.mkdir('data_gz')


top += f'// filename: {f}.gz.h\n'
top += f'#define {output_charp}_len {gzlen}\n'
top += f'const char {output_charp}[] = '
top += '{'

with open(output_file, 'wb') as f_out:
for i, b in enumerate(gz):
if not i%10:
top += '\n '
top += f'0x{b:02X}, '
top = top[:-2]
top += '};'
f_out.write(top.encode(encoding='utf-8'))


src='data/'
out='compress/'

if not 'compress' in os.listdir():
os.mkdir('compress')

for f in os.listdir(src):
convert_to_gzip(src, out, f)
for f in os.listdir(src_dir):
with open(f'{src_dir}/{f}', 'rb') as f_in:
with gzip.open(f'{out_dir}/{f}.gz', 'wb') as f_out:
f_out.writelines(f_in)

+ 12
- 0
data/compress.html View File

<!DOCTYPE html>
<html>

<head>
<title>Ich bin ein komrpimierter Test</title>
I bims der Head
</head>
<body>
I bims der Body
</body>

</html>

+ 7
- 0
data/index.html View File

</div> </div>
</div> </div>


<div class="terminal">
<input type="button" id="clear_term" value="clear" onclick="clearTerminal();">
<input type="checkbox" id="scroll" name="scroll" value="scroll">
<label for="scroll"> autoscroll </label>
<textarea id="term"> waiting for log messages ... </textarea>
</div>

</body> </body>


<script src="/input.js"></script> <script src="/input.js"></script>

+ 38
- 6
data/input.js View File

var slider = document.getElementById("range1");
var output = document.getElementById("l_pwm");
output.innerHTML = slider.value; // Display the default slider value
// var slider = document.getElementById("helligkeit");
// var output = document.getElementById("l_pwm");
// output.innerHTML = slider.value; // Display the default slider value


// Update the current slider value (each time you drag the slider handle)
slider.oninput = function() {
output.innerHTML = this.value;
// // Update the current slider value (each time you drag the slider handle)
// slider.oninput = function() {
// output.innerHTML = this.value;
// }



let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if (xhr.status == 200){
console.log(xhr.responseText);
terminal = document.getElementById("term");
autoscroll = document.getElementById("scroll");
terminal.innerHTML += xhr.responseText + '\n';
if(autoscroll.checked)
terminal.scrollTop = terminal.scrollHeight;
}
else {
console.log("status:", xhr.status);
}
}
}

function reloadTerminal() {
xhr.open("POST", "/app=terminal", true);
xhr.send();
setTimeout(reloadTerminal, 1000);
};

reloadTerminal();

function clearTerminal() {
document.getElementById("term").innerHTML = '';
} }

+ 19
- 1
data/style.css View File

font-family: sans-serif, Arial, Helvetica; font-family: sans-serif, Arial, Helvetica;
background-color: #d4d4d4; background-color: #d4d4d4;
height: 100%; height: 100%;
background-image: url('Background.png');
/* background-image: url('Background.png'); */
background-repeat: repeat; background-repeat: repeat;
background-size: 150% 150%; background-size: 150% 150%;
} }
-ms-transform: translateX(26px); -ms-transform: translateX(26px);
transform: translateX(26px); transform: translateX(26px);
} }
*/

.terminal {
margin:5%;
padding: 1%;
width: 80%;
border: 1px solid black;
border-radius: 5px;
}

#term {
font-size: large;
width: 100%;
height: 10em;
}


#clear_term {
margin: 2px;
}

+ 12
- 3
doku.md View File

- maybe compress files ? - maybe compress files ?




LED Flickering issue
### LED Flickering issue
https://github.com/NachtRaveVL/PCA9685-Arduino/issues/15 https://github.com/NachtRaveVL/PCA9685-Arduino/issues/15
PlatformIO Library veraltet !!


PlatformIO Library veraltet


### TIMER in OTA unterbrechen !!!!!


###TIMER in OTA unterbrechen !!!!!


### further improvments
with streamFile gzip encoded Files can be sent
this reduces space on fs !
new easier script needed to just convert to .gz
maybe measure timings on ESP

__=> use serveStatic because way simpler !__

+ 0
- 48
include/httpserver.h View File

#ifndef __HTTPSERVER_H
#define __HTTPSERVER_H

#include "filesys.h"
#include <ESP8266WebServer.h>


class HTTPServer : public ESP8266WebServer {
private:
const char* rootDir;
bool addRootFileHandler();
bool formatFS() {
return format_fs();
}
void listRoot() {
ls(rootDir);
}

public:
HTTPServer(const int _port, const char* _rootDir) :
ESP8266WebServer(_port), rootDir(_rootDir)
{ }
~HTTPServer()
{
Serial.printf("[HTTPServer] shut down ...\n\r");
}

bool start() {
if(!mount_fs())
return false;
Serial.printf("[HTTPServer] LittleFS mounted !\n\r");

Serial.printf("[HTTPServer] root:\n\r");
this->listRoot();
Serial.printf("\n\r");

if( this->addRootFileHandler() ){
this->begin();
Serial.printf("[HTTPServer] Server active on Port 80 !\n\r");
return true;
}
Serial.printf("[HTTPServer] Not starting Server, something went wrong !\n\r");
return false;
}
};

#endif // __HTTPSERVER_H

+ 2
- 6
include/ota.h View File

#ifndef __OTA_H
#define __OTA_H
#pragma once


#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <WiFiUdp.h> #include <WiFiUdp.h>
}); });
ArduinoOTA.begin(); ArduinoOTA.begin();


}


#endif // __OTA_H
}

src/filesys.cpp → lib/httpserver/filesys.cpp View File

#include "filesys.h" #include "filesys.h"


// listDir("/");
// deleteFile("/hello.txt");
// writeFile("/hello.txt", "Hello ");
// appendFile("/hello.txt", "World!\n\r");
// readFile("/hello.txt");
// listDir("/");

FSInfo fsinfo; FSInfo fsinfo;


bool mount_fs() { bool mount_fs() {
Serial.println(); Serial.println();
} }


void readFile(const char * path) {
File open(const char * path) {
return LittleFS.open(path, "r");
}


void printFile(const char * path) {
Serial.printf("Reading file: %s\n\r", path); Serial.printf("Reading file: %s\n\r", path);


File file = LittleFS.open(path, "r"); File file = LittleFS.open(path, "r");

include/filesys.h → lib/httpserver/filesys.h View File

#ifndef __FILESYS_H
#define __FILESYS_H
#pragma once


#include <LittleFS.h> #include <LittleFS.h>


// some usefull wrappers for Filesystem

bool mount_fs(); bool mount_fs();
bool format_fs(); bool format_fs();


File open(const char * path);

void ls(const char * dirname); void ls(const char * dirname);
void readFile(const char * path);
void printFile(const char * path);
void writeFile(const char * path, const char * message); void writeFile(const char * path, const char * message);
void appendFile(const char * path, const char * message); void appendFile(const char * path, const char * message);
void renameFile(const char * path1, const char * path2); void renameFile(const char * path1, const char * path2);
void deleteFile(const char * path); void deleteFile(const char * path);

#endif // __FILESYS_H

+ 42
- 0
lib/httpserver/httpserver.cpp View File

#include "httpserver.h"

bool HTTPServer::start() {
if(!mount_fs()) {
logf("cant mount filesystem, EXIT !\n\r");
return false;
}
logf("[HTTPServer] LittleFS mounted !\n\r");
logf("[HTTPServer] root:\n\r");
this->listRoot();
logf("\n\r");

// default handler
this->onNotFound([this]() {
String message = "File Not Found\n\n";
message += "URI: ";
message += uri();
message += "\nMethod: ";
message += (method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += args();
message += "\n";

for (uint8_t i = 0; i < args(); i++) {
message += " " + argName(i) + ": " + arg(i) + "\n";
}
send(404, "text/plain", message);
});

// add static root file handler for http
this->serveStatic("/", LittleFS, "/");
// application handler
this->on("/app=terminal", HTTP_POST, [this]() {
String log_msg = "terminal: millis: ";
log_msg += millis();
send(200, "text/plain", log_msg);
});

this->begin();
Serial.printf("[HTTPServer] Server active on Port 80 !\n\r");
}

+ 41
- 0
lib/httpserver/httpserver.h View File

// Wrapper for ESP8266WebServer with Filesystem as HTTP source

#pragma once

#include <ESP8266WebServer.h>
#include <stdarg.h>
#include "filesys.h"

// debug log <ESP8266WebServer.h>
// #define DEBUGV(f,...) do { Serial.printf(PSTR(f), ##__VA_ARGS__); } while (0)

#define LOG_STR "[HTTPServer]"


class HTTPServer : public ESP8266WebServer {

private:
const char* rootDir = "/";
void listRoot() {
ls(rootDir);
}
void logf(const char *format, ...) {
va_list args;
va_start(args, format);
Serial.print(LOG_STR);
Serial.printf(format, args);
va_end(args);
}

public:
HTTPServer(const int _port, const char* _rootDir) :
ESP8266WebServer(_port), rootDir(_rootDir)
{ }
~HTTPServer()
{
Serial.printf("[HTTPServer] shut down ...\n\r");
}

bool start();
};

+ 57
- 51
lib/treppe/treppe.cpp View File

else { else {
current_pwm += stepsize; current_pwm += stepsize;
} }
Serial.println((uint16_t)current_pwm);
// Serial.println((uint16_t)current_pwm);
pwmController.setChannelPWM(led, (uint16_t)current_pwm); pwmController.setChannelPWM(led, (uint16_t)current_pwm);
if(current_pwm > stopval - stepsize && current_pwm < stopval + stepsize){ if(current_pwm > stopval - stepsize && current_pwm < stopval + stepsize){
if(stopval == 0) pwmController.setChannelPWM(led, 0); if(stopval == 0) pwmController.setChannelPWM(led, 0);
lastbrightness = active_brightness; lastbrightness = active_brightness;
} }
status = status_build; // set parameter memory status = status_build; // set parameter memory
Serial.print("----Status Changed! onoff: ");
Serial.print(state);
Serial.print(" dir: ");
Serial.println(direction);


Serial.printf("----Status Changed! onoff: %d, dir: %d\n", state, direction);
} }
if(!finish){ // finish == 0 -> action pending if(!finish){ // finish == 0 -> action pending
if(!softstart_led(led,lastbrightness, brightness)){
Serial.print("one LED finished: ");
Serial.print(led);
Serial.print(" last: ");
Serial.print(lastbrightness);
Serial.print(" curr: ");
Serial.println(brightness);
if(direction){
led++;
if(led >= stairs) {
if(!softstart_led(led,lastbrightness, brightness)){
Serial.printf("one LED finished: led: %d, last: %d, curr %d\n",
led, lastbrightness, brightness);

if(direction){
led++;
if(led >= stairs)
finish = 1;
}
else{
led--;
if(led < 0)
finish = 1; finish = 1;
//lastbrightness = brightness;
}
}
else{
led--;
if(led < 0){
//lastbrightness = brightness;
finish = 1;
}
}
} }
}
} }
} }



void Treppe::task_2()
void Treppe::rampe()
{ {
if(state) { if(state) {
finish = 0;
state = 0; // set parameter memory
}

if(!finish) {
if(direction) { // aufwärts if(direction) { // aufwärts
if(tick >= ticks_treppe-1) { // ziel erreicht if(tick >= ticks_treppe-1) { // ziel erreicht
Serial.println("[Treppe] oberster tick !"); Serial.println("[Treppe] oberster tick !");
state = 0;
finish = 1;
return; return;
} }
tick++; // eins hoch tick++; // eins hoch
else { // abwärts else { // abwärts
if(tick <= 0) { // ziel erreicht if(tick <= 0) { // ziel erreicht
Serial.println("[Treppe] unterster tick !"); Serial.println("[Treppe] unterster tick !");
state = 0;
finish = 1;
return; return;
} }
tick--; // eins runter tick--; // eins runter
} }


stufe = tick / ticks_pro_stufe; stufe = tick / ticks_pro_stufe;
float new_pwm = differenz_pwm_pro_tick * (tick - ticks_pro_stufe*stufe);
if(direction)
new_pwm += differenz_pwm_pro_tick;
new_pwm += idle_brightness;

float new_pwm = 0.0;
if(an_aus) {
new_pwm = differenz_pwm_pro_tick * (tick - ticks_pro_stufe*stufe);
new_pwm += idle_brightness;
if(direction) new_pwm += differenz_pwm_pro_tick;
}
else {
new_pwm = active_brightness - differenz_pwm_pro_tick * (tick - ticks_pro_stufe*stufe);
new_pwm += idle_brightness;
if(direction) new_pwm -= differenz_pwm_pro_tick;
}


pwmController.setChannelPWM(stufe, (uint16_t) new_pwm); pwmController.setChannelPWM(stufe, (uint16_t) new_pwm);
Serial.printf("tick %04u, led %02d:%02u, pwm %4.1f\n", Serial.printf("tick %04u, led %02d:%02u, pwm %4.1f\n",
} }
} }


// if(stufe > stairs || stufe < 0 || tick < 0 || tick > ticks_treppe-1) {
// Serial.println("[Treppe] ERROR, Something went wrong !");
// state = 0;
// return;
// }

void Treppe::setup(){ void Treppe::setup(){
Serial.printf("differenz_pwm_pro_tick %f\n", differenz_pwm_pro_tick); Serial.printf("differenz_pwm_pro_tick %f\n", differenz_pwm_pro_tick);
current_sensor_state[1] = digitalRead(SENSOR2); current_sensor_state[1] = digitalRead(SENSOR2);
if(current_sensor_state[0] && !last_sensor_state[0] && state == 0){ if(current_sensor_state[0] && !last_sensor_state[0] && state == 0){
setTick(0);
setAnAus(1);
setDirection(1); setDirection(1);
setState(1); setState(1);
} }


if(current_sensor_state[1] && !last_sensor_state[1] && state == 0){ if(current_sensor_state[1] && !last_sensor_state[1] && state == 0){
setTick(0);
setAnAus(0);
setDirection(0); setDirection(0);
setState(1); setState(1);
} }


// first switch - off approach, use timer later // first switch - off approach, use timer later
if(!current_sensor_state[0] && last_sensor_state[0] && state == 1){ if(!current_sensor_state[0] && last_sensor_state[0] && state == 1){
setTick(ticks_treppe);
setAnAus(1);
setDirection(1); setDirection(1);
setState(0); setState(0);
} }


if(!current_sensor_state[1] && last_sensor_state[1] && state == 1){ if(!current_sensor_state[1] && last_sensor_state[1] && state == 1){
setTick(ticks_treppe);
setAnAus(1);
setDirection(0); setDirection(0);
setState(0); setState(0);
} }


last_sensor_state[0] = current_sensor_state[0]; last_sensor_state[0] = current_sensor_state[0];
last_sensor_state[1] = current_sensor_state[1]; last_sensor_state[1] = current_sensor_state[1];
<<<<<<< HEAD
=======

>>>>>>> 3d13e761f497a0408c134059ff0dfadaa93ebbf4
ledsequence(); ledsequence();
} }


return time_per_stair; return time_per_stair;
} }


uint8_t Treppe::setDirection(uint8_t _direction){
void Treppe::setDirection(uint8_t _direction){
switch_direction = _direction; switch_direction = _direction;
Serial.println("Treppe: Direction changed!");
Serial.printf("Treppe: switch_direction=%d!\n", switch_direction);
if(finish) Serial.println("apply direction request immediately"); if(finish) Serial.println("apply direction request immediately");
else Serial.println("currently active, dir change afterwards"); else Serial.println("currently active, dir change afterwards");
// to do: implement state command variable to determine dimm-state // to do: implement state command variable to determine dimm-state
return switch_direction;
} }


uint8_t Treppe::setState(uint8_t _state){
if(state == _state) return 1;
else{
switch_state = _state;
Serial.println("Treppe: State Request changed!");
if(finish) Serial.println("apply state request immediately");
else Serial.println("currently active, state changes after activity");
}
return 0;
void Treppe::setState(uint8_t _state){
if(state == _state) return;
else {
switch_state = _state;
Serial.printf("Treppe: switch_state=%d!\n", switch_state);
if(finish) Serial.println("apply state request immediately");
else Serial.println("currently active, state changes after activity");
}
} }

+ 12
- 5
lib/treppe/treppe.h View File

uint8_t switch_state = 0; uint8_t switch_state = 0;
uint8_t finish = 1; uint8_t finish = 1;


// alternative
uint32_t tick = 0; uint32_t tick = 0;
uint32_t stufe = 0; uint32_t stufe = 0;
uint8_t an_aus = 0;


uint32_t ticks_treppe = 0; uint32_t ticks_treppe = 0;
uint32_t ticks_pro_stufe = 0; uint32_t ticks_pro_stufe = 0;
float differenz_pwm_pro_tick = 0.0; float differenz_pwm_pro_tick = 0.0;
// alternative



// initialize with i2c-Address 0, use Wire Library // initialize with i2c-Address 0, use Wire Library
PCA9685 pwmController; PCA9685 pwmController;
uint8_t softstart_led(uint8_t led, uint16_t startval, uint16_t stopval); uint8_t softstart_led(uint8_t led, uint16_t startval, uint16_t stopval);
void ledsequence(); void ledsequence();
void rampe();


public: public:
Treppe(uint8_t _stairs) : stairs(_stairs){ Treppe(uint8_t _stairs) : stairs(_stairs){
/ (float) ticks_pro_stufe; / (float) ticks_pro_stufe;
} }


void task(); // call periodically

void setup(); void setup();
void task_2();
void task(); // call periodically


// Parameter section // Parameter section
uint16_t setIdle(uint16_t _idle_brightness); uint16_t setIdle(uint16_t _idle_brightness);
} }


// Runtime Parameter section // Runtime Parameter section
uint8_t setDirection(uint8_t _direction);
uint8_t setState(uint8_t _state);
void setDirection(uint8_t _direction);
void setState(uint8_t _state);
void setAnAus(uint8_t _an_aus) {
an_aus = _an_aus;
}


uint8_t getState() { return state;}; uint8_t getState() { return state;};
uint8_t getFinished() { return finish;};
uint8_t getDirection() {return direction;}; uint8_t getDirection() {return direction;};
}; };

+ 0
- 17
src/httpserver.cpp View File

#include "httpserver.h"


bool HTTPServer::addRootFileHandler() {

// //experimental, see doku.md
// server.serveStatic("/compressed", LittleFS, "/compressed.html.gzip");

this->serveStatic("", LittleFS, "/index.html");
this->serveStatic("/", LittleFS, "/index.html");
this->serveStatic("/#", LittleFS, "/index.html");
this->serveStatic("/style.css", LittleFS, "/style.css");
this->serveStatic("/input.js", LittleFS, "/input.js");
this->serveStatic("/favicon.png", LittleFS, "/favicon.png");

return true;
}

+ 2
- 23
src/main.cpp View File

#include "user_interface.h" #include "user_interface.h"
} }
// OTA & WEB // OTA & WEB
#include "ota.h"
#include "wifi_credentials.h" #include "wifi_credentials.h"
#include "ota.h"
#include "httpserver.h" #include "httpserver.h"


// BOARD // BOARD
stairs.task(); stairs.task();
} }


// HTTP
void handleNotFound();
// port 80, root directory of server '/'
HTTPServer httpServer(80, "/"); HTTPServer httpServer(80, "/");


uint32_t _t=0; uint32_t _t=0;
// =============================================== // ===============================================




void handleNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
message += httpServer.uri();
message += "\nMethod: ";
message += (httpServer.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += httpServer.args();
message += "\n";

for (uint8_t i = 0; i < httpServer.args(); i++) {
message += " " + httpServer.argName(i) + ": " + httpServer.arg(i) + "\n";
}

httpServer.send(404, "text/plain", message);
}


void setup() { void setup() {
#ifdef WITH_DEBUGGING_ON #ifdef WITH_DEBUGGING_ON
ota_setup(); ota_setup();


httpServer.start(); httpServer.start();
httpServer.onNotFound(handleNotFound);
Serial.println("HTTP server started !"); Serial.println("HTTP server started !");


stairs.setup(); stairs.setup();


os_timer_setfn(&timer1, timerCallback, &timer_flag); os_timer_setfn(&timer1, timerCallback, &timer_flag);
os_timer_arm(&timer1, 20, true); os_timer_arm(&timer1, 20, true);

stairs.setState(1);
stairs.setDirection(1);
} }


#include <random> #include <random>

+ 42
- 3
templ_platformio_ini View File

; Please visit documentation for the other options and examples ; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html


[env]
[platformio]
description = ESP8266 Treppenlicht Steuerung
default_envs = ota
; test_dir = test
data_dir = data_gz

[env:hardware]
platform = espressif8266 platform = espressif8266
board = nodemcuv2 board = nodemcuv2
framework = arduino framework = arduino


; for http files
board_build.filesystem = littlefs board_build.filesystem = littlefs
board_build.ldscript = eagle.flash.4m1m.ld board_build.ldscript = eagle.flash.4m1m.ld
extra_scripts = pre:create_gz_files.py extra_scripts = pre:create_gz_files.py

monitor_speed = 115200 monitor_speed = 115200


[env:serial] [env:serial]
extends = env:hardware
upload_protocol = esptool upload_protocol = esptool
upload_speed = 921600 upload_speed = 921600


[env:ota] [env:ota]
extends = env:hardware
; OTA => https://docs.platformio.org/en/latest/platforms/espressif8266.html#over-the-air-ota-update ; OTA => https://docs.platformio.org/en/latest/platforms/espressif8266.html#over-the-air-ota-update
upload_protocol = espota upload_protocol = espota
upload_port = <!! IP ADDRESS !!> upload_port = <!! IP ADDRESS !!>
--host_port=<!! PORT !!> --host_port=<!! PORT !!>
--auth=admin --auth=admin



[env:debug] [env:debug]
extends = env:hardware
; look at doku.md ; look at doku.md
build_flags = -DWITH_DEBUGGING_ON -Os -g3 -ggdb3 build_flags = -DWITH_DEBUGGING_ON -Os -g3 -ggdb3
upload_protocol = esptool upload_protocol = esptool
upload_speed = 921600 upload_speed = 921600




# This file is used compile and run tests located in the `unit` directory.
# For more info, see:
# https://docs.platformio.org/en/latest/plus/unit-testing.html
# https://github.com/ThrowTheSwitch/Unity
# https://github.com/ThrowTheSwitch/Unity/blob/master/docs/UnityAssertionsReference.md



# To prepare coverage data for lcov, add ${coverage.build_flags} to env:test build flags
# To actually generate coverage report:
# $ `pio test` / run the test `program` manually
# $ lcov --include (readlink -f ../espurna)'/*' --capture --directory .pio/build/test/ --output-file test.info
# $ genhtml --ignore-errors source test.info --output-directory out

[coverage]
build_flags = -lgcov -fprofile-arcs -ftest-coverage

[env:test]
extends = env:hardware



[env:native]
platform = native
test_build_project_src = true
build_flags =
-DMANUFACTURER="PLATFORMIO"
-DDEVICE="TEST"
-std=gnu++11
-g
-Os
-I lib/treppe
-I lib/PCA9685-Arduino





+ 1
- 2
test/test_pwm.cpp View File

#include <Arduino.h>
// #include <Arduino.h>
#include "treppe.h" #include "treppe.h"

#include <unity.h> #include <unity.h>


Treppe stairs(10); Treppe stairs(10);

Loading…
Cancel
Save