Skip to content

Commit

Permalink
Improve sample applications (#2756)
Browse files Browse the repository at this point in the history
This PR updates all the main Sming samples to try and demonstrate best practice when coding Sming applications. Specifically:

- Initialise timers using templated methods where possible as this provides static range check on values
- Using `SimpleTimer` is sufficient in most cases. This is both more efficient and avoids complication where compiler cannot distinguish between delegates and callback functions.
- Use timer `startOnce()` method rather than `start(false)`
- Use C++ iterators in preference to C-style loops `for(int i=0; i<list.count(); ++i) {...}`
- Ensure consistent use of `WIFI_SSID` and `WIFI_PASSWORD`
- Use `Serial` methods in preference to `debug_x` where intent is not actually for debugging
- Use anonymous namespaces and remove redundant static declarations
- Avoid nested `if` statements
- Place `init()` function at end of main application source file
- Reduce variable scope (declare at point of first use)
- static/global variables do not require explicit initialisation to 0


Sample-specific changes:

- Revise `HttpServer_AJAX` so that GPIO numbers are consistent with web code
- Update Basic_Ssl keys, requires Bearssl
- Update Basic_DateTime sample
  - Simplify code using LineBuffer
  - Accept either numeric timestamp or HTTP date string. Note: ISO8601 string conversion not currently supported by `DateTime`.
  - Don't emulate console via telnet, use default CLI
- Rewrite Basic_Neopixel sample
  - Enumerate color values
  - Reduce global variables and duplicated code
  - Verify logic flow using Host
- Rewrite Display_TM1637 as state machine (coroutine)
- Fix Basic_Storage, didn't actually use RAM as indicated
- Add Host `Print` stream support, update `Basic_Utility` sample


Other changes

- Update `jerryscript` library to latest. CI improvements and removes deprecation warnings.
- Fix bad memory casts in si4432 library. Also builds for other architectures than esp8266, so remove SOC restrictions.
- Fix unused variable warning in `CommandProcessing` library
  • Loading branch information
mikee47 authored Apr 5, 2024
1 parent c487f91 commit 8843f26
Show file tree
Hide file tree
Showing 113 changed files with 1,878 additions and 1,464 deletions.
50 changes: 50 additions & 0 deletions Sming/Arch/Host/Components/hostlib/include/hostlib/Streams.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Streams.h - Print support for host output
*
* Copyright 2024 mikee47 <[email protected]>
*
* This file is part of the Sming Framework Project
*
* This library is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, version 3 or later.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with SHEM.
* If not, see <https://www.gnu.org/licenses/>.
*
****/

#pragma once

#include <unistd.h>

namespace Host
{
class OutputStream : public Print
{
public:
OutputStream(int fileno) : fileno(fileno)
{
}

virtual size_t write(uint8_t c) override
{
return write(&c, 1);
}

size_t write(const uint8_t* buffer, size_t size) override
{
return ::write(fileno, buffer, size);
}

private:
int fileno;
};

OutputStream standardOutput(STDOUT_FILENO);
OutputStream standardError(STDERR_FILENO);

}; // namespace Host
2 changes: 2 additions & 0 deletions Sming/Components/Storage/src/include/Storage/SysMem.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class SysMem : public Device
class SysMemPartitionTable : public PartitionTable
{
public:
using PartitionTable::add;

/**
* @brief Add partition entry for FlashString data access
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@ void init()
// Auto reporting is enabled by default.
// Use bleGamepad.setAutoReport(false); to disable auto reporting, and then use bleGamepad.sendReport(); as needed

procTimer.initializeMs(500, loop).start();
procTimer.initializeMs<500>(loop).start();
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ void init()
Serial.println("Starting BLE Keyboard sample!");
bleKeyboard.begin();

procTimer.initializeMs(1000, loop).start();
procTimer.initializeMs<1000>(loop).start();
}
25 changes: 13 additions & 12 deletions Sming/Libraries/CS5460/samples/generic/app/application.cpp
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
#include <SmingCore.h>
#include <CS5460.h>

namespace
{
CS5460 powerMeter(PIN_NDEFINED, PIN_NDEFINED, PIN_NDEFINED, PIN_NDEFINED);

Timer printVoltageTimer;
SimpleTimer printVoltageTimer;

void printVoltage()
{
debugf("Measured RMS voltage is: %f", powerMeter.getRMSVoltage());
Serial << _F("Measured RMS voltage is: ") << powerMeter.getRMSVoltage() << endl;
}

} // namespace

void init()
{
Serial.begin(SERIAL_BAUD_RATE, SERIAL_8N1,
SERIAL_FULL); // 115200 by default, GPIO1,GPIO3, see Serial.swap(), HardwareSerial
Serial.begin(SERIAL_BAUD_RATE);
Serial.systemDebugOutput(true);

powerMeter.init();
powerMeter.setCurrentGain(190.84); //0.25 / shunt (0.00131)
powerMeter.setVoltageGain(500); //0.25V (Veff max) * dividerGain
uint32_t conf = 0;
conf = powerMeter.readRegister(CONFIG_REGISTER);
conf |= ENABLE_VOLTAGE_HPF;
conf |= ENABLE_CURRENT_HPF;
powerMeter.setCurrentGain(190.84); // 0.25 / shunt (0.00131)
powerMeter.setVoltageGain(500); // 0.25V (Veff max) * dividerGain

uint32_t conf = powerMeter.readRegister(CONFIG_REGISTER);
conf |= ENABLE_VOLTAGE_HPF | ENABLE_CURRENT_HPF;
powerMeter.writeRegister(CONFIG_REGISTER, conf);
powerMeter.startMultiConvert();

printVoltageTimer.initializeMs(1000, printVoltage).start();
printVoltageTimer.initializeMs<1000>(printVoltage).start();
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ bool processTelnetInput(TcpClient& client, char* data, int size)
char c = *data++;
if(skip) {
--skip;
} else if(c == '\xff') {
} else if(c == TC_ESC) {
skip = 2;
} else {
commandHandler.process(c);
Expand Down
6 changes: 3 additions & 3 deletions Sming/Libraries/DS18S20/ds18s20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void DS18S20::StartMeasure()
InProgress=true;
ds->begin();
ds->reset_search();
DelaysTimer.initializeMs(150, TimerDelegate(&DS18S20::DoSearch, this)).start(false);
DelaysTimer.initializeMs<150>(TimerDelegate(&DS18S20::DoSearch, this)).start(false);
}

}
Expand Down Expand Up @@ -146,7 +146,7 @@ void DS18S20::StartReadNext()
ds->select(addr);
ds->write(STARTCONVO, 1); // start conversion, with parasite power on at the end

DelaysTimer.initializeMs(900, TimerDelegate(&DS18S20::DoMeasure, this)).start(false);
DelaysTimer.initializeMs<900>(TimerDelegate(&DS18S20::DoMeasure, this)).start(false);
}
else
{
Expand Down Expand Up @@ -210,7 +210,7 @@ void DS18S20::DoMeasure()
debugx(" DBG: Temperature = %f Celsius, %f Fahrenheit",celsius[numberOfread],fahrenheit[numberOfread]);

numberOfread++;
DelaysTimer.initializeMs(100, TimerDelegate(&DS18S20::StartReadNext, this)).start(false);
DelaysTimer.initializeMs<100>(TimerDelegate(&DS18S20::StartReadNext, this)).start(false);

}

Expand Down
49 changes: 26 additions & 23 deletions Sming/Libraries/ModbusMaster/samples/generic/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,28 @@
#define MB_SLAVE_ADDR 1
#define SLAVE_REG_ADDR 1

Timer mbLoopTimer;

namespace
{
SimpleTimer mbLoopTimer;
ModbusMaster mbMaster;
HardwareSerial modbusComPort(UART_ID_0);
HardwareSerial debugComPort(UART_ID_1);

uint16_t globalSeconds = 0;
uint16_t globalSeconds;

void mbLoop()
{
globalSeconds++;

uint8_t numberOfRegistersToWrite = 1;
uint8_t bufferPosition = 0;
const uint8_t numberOfRegistersToWrite = 1;
const uint8_t bufferPosition = 0;
mbMaster.begin(MB_SLAVE_ADDR, modbusComPort);
mbMaster.setTransmitBuffer(bufferPosition, globalSeconds);
mbMaster.writeMultipleRegisters(SLAVE_REG_ADDR, numberOfRegistersToWrite);

uint8_t nrOfRegistersToRead = 1;
uint8_t mbResult = mbMaster.readHoldingRegisters(SLAVE_REG_ADDR, nrOfRegistersToRead); //see also readInputRegisters
// see also readInputRegisters
const uint8_t nrOfRegistersToRead = 1;
uint8_t mbResult = mbMaster.readHoldingRegisters(SLAVE_REG_ADDR, nrOfRegistersToRead);

if(mbResult == mbMaster.ku8MBSuccess) {
/*
Expand All @@ -34,9 +36,9 @@ void mbLoop()
debugComPort.printf("Reg %d: %d\r\n", i, buffer[i]);
}
*/
debugf("Data from slave: %d", mbMaster.getResponseBuffer(0));
debug_i("Data from slave: %d", mbMaster.getResponseBuffer(0));
} else {
debugf("Res err: %d", mbResult);
debug_i("Res err: %d", mbResult);
}

mbMaster.clearResponseBuffer();
Expand All @@ -57,57 +59,58 @@ void mbLogReceive(const uint8_t* adu, size_t aduSize, uint8_t status)
if(status != mbMaster.ku8MBSuccess) {
switch(status) {
case mbMaster.ku8MBIllegalFunction:
debugf("MB Illegal Function");
debug_i("MB Illegal Function");
break;
case mbMaster.ku8MBIllegalDataAddress:
debugf("MB Illegal Address");
debug_i("MB Illegal Address");
break;
case mbMaster.ku8MBIllegalDataValue:
debugf("MB Illegal Data Value");
debug_i("MB Illegal Data Value");
break;
case mbMaster.ku8MBSlaveDeviceFailure:
debugf("MB Slave Device Failure");
debug_i("MB Slave Device Failure");
break;
case mbMaster.ku8MBInvalidSlaveID:
debugf("MB Invalid Slave ID");
debug_i("MB Invalid Slave ID");
break;
case mbMaster.ku8MBInvalidFunction:
debugf("MB Invalid function");
debug_i("MB Invalid function");
break;
case mbMaster.ku8MBResponseTimedOut:
debugf("MB Response Timeout");
debug_i("MB Response Timeout");
break;
case mbMaster.ku8MBInvalidCRC:
debugf("MB Invalid CRC");
debug_i("MB Invalid CRC");
break;
case mbMaster.ku8MBResponseTooLarge:
debugf("MB Response too large");
debug_i("MB Response too large");
break;
}
debugf("ADU Size: %d, status: %d ", aduSize, status);
debug_i("ADU Size: %d, status: %d ", aduSize, status);
debug_hex(INFO, "RX ADU", adu, aduSize);
}
debugf("\r\n");
debug_i("\r\n");
}

void mbLogTransmit(const uint8_t* adu, size_t aduSize)
{
debug_hex(INFO, "TX ADU", adu, aduSize);
}

} // namespace

void init()
{
pinMode(RS485_RE_PIN, OUTPUT);
digitalWrite(RS485_RE_PIN, LOW);
modbusComPort.begin(MODBUS_COM_SPEED, SERIAL_8N1, SERIAL_FULL);
debugComPort.begin(SERIAL_BAUD_RATE, SERIAL_8N1,
SERIAL_TX_ONLY); // 115200 by default, GPIO1,GPIO3, see Serial.swap(), HardwareSerial
debugComPort.begin(SERIAL_BAUD_RATE, SERIAL_8N1, SERIAL_TX_ONLY);
debugComPort.systemDebugOutput(true);

mbMaster.preTransmission(preTransmission);
mbMaster.postTransmission(postTransmission);
mbMaster.logReceive(mbLogReceive);
mbMaster.logTransmit(mbLogTransmit);

mbLoopTimer.initializeMs(1000, mbLoop).start();
mbLoopTimer.initializeMs<1000>(mbLoop).start();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void onConnect(NimBLEServer& server)
{
Serial.println("Connected :) !");

procTimer.initializeMs(500, loop).start();
procTimer.initializeMs<500>(loop).start();
}

void onDisconnect(NimBLEServer& server)
Expand Down
1 change: 0 additions & 1 deletion Sming/Libraries/si4432/component.mk

This file was deleted.

16 changes: 7 additions & 9 deletions Sming/Libraries/si4432/si4432.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,16 +354,16 @@ void Si4432::BurstWrite(Registers startReg, const byte value[], uint8_t length)
// _spi->enable();
_spi->beginTransaction(_spi->SPIDefaultSettings);
delayMicroseconds(1);
// _spi->send(&regVal, 1);
_spi->transfer(&regVal, 1);
_spi->transfer(regVal);

#if DEBUG_VERBOSE_SI4432
debugf("Writing: %x | %x ... %x (%d bytes)", (regVal != 0xFF ? (regVal) & 0x7F : 0x7F),
value[0], value[length-1], length);
#endif

// _spi->send(value, length);
_spi->transfer((uint8 *)value, length);
uint8_t buffer[length];
memcpy(buffer, value, length);
_spi->transfer(buffer, length);

// _spi->disable();
_spi->endTransaction();
Expand All @@ -376,13 +376,11 @@ void Si4432::BurstRead(Registers startReg, byte value[], uint8_t length) {
// _spi->enable();
_spi->beginTransaction(_spi->SPIDefaultSettings);
delayMicroseconds(1);
// _spi->send(&regVal, 1);
_spi->transfer(&regVal, 1);
_spi->transfer(regVal);

// _spi->setMOSI(HIGH); /* Send 0xFF */
_spi->transfer((uint8 *)0xFF, 1);
// _spi->recv(value, length);
_spi->transfer((uint8 *)value, length);
_spi->transfer(0xff);
_spi->transfer(value, length);

#if DEBUG_VERBOSE_SI4432
debugf("Reading: %x | %x..%x (%d bytes)", (regVal != 0x7F ? (regVal) & 0x7F : 0x7F),
Expand Down
3 changes: 2 additions & 1 deletion samples/Accel_Gyro_MPU6050/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ void init()

Wire.begin(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN);
mpu.initialize();
Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
bool success = mpu.testConnection();
Serial << _F("MPU6050 connection ") << (success ? _F("successful") : _F("failed")) << endl;

mainLoopTimer.initializeMs<mainLoopInterval>(mainLoop).start();
}
6 changes: 3 additions & 3 deletions samples/Accelerometer_MMA7455/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

// For more information read: https://code.google.com/p/mma-7455-arduino-library/
MMA_7455 accel;
Timer procTimer;
SimpleTimer procTimer;

void readSensor()
{
Serial.println("Reading..");
Serial.println(_F("Reading.."));

int8_t x = accel.readAxis('x');
int8_t y = accel.readAxis('y');
Expand All @@ -29,5 +29,5 @@ void init()
accel.initSensitivity(MMA_7455_2G_MODE);

// Start reading loop
procTimer.initializeMs(300, readSensor).start();
procTimer.initializeMs<300>(readSensor).start();
}
Loading

0 comments on commit 8843f26

Please sign in to comment.