@BartE said:
@Axel yes you can use this sketch stand alone.
In the sketch just:
- remove #include <MySensor.h> and #include <SPI.h>
- remove MyMessage from struct LEDS (6 times on 4 lines)
- remove all lines with "gw." except for gw.wait() replace this function with delay()
- remove the function incomingMessage
That should be it, not sure if all compilers are gone now (did not test it)
And of course there is no needs anymore to add the NFR radio module
Hello BartE
Could you post the sketch (post 1) for Mysensors2.0.0, please?
Or what I have to change on this sketch to make it's compilated with arduino 1.6.9 Mysensors Library 2.0.0
2 hours and "Done compiling". So I have wrong library version. And now It's ready to upload.
/**
* REVISION HISTORY
* Version 1.0 - February 15, 2014 - Bruce Lacey
* Version 1.1 - August 13, 2014 - Converted to 1.4 (hek)
* Version 1.2 - Januari 2016 - Bart Eversdijk
*
* DESCRIPTION
* This sketch provides a Dimmable LED Light using PWM and based on Henrik Ekblad
* <henrik.ekblad@gmail.com> Vera Arduino Sensor project.
* Developed by Bruce Lacey, inspired by Hek's MySensor's example sketches.
*
* The circuit uses a MOSFET for Pulse-Wave-Modulation to dim the attached LED or LED strip.
* The MOSFET Gate pin is connected to Arduino pin 3 (LED_PIN), the MOSFET Drain pin is connected
* to the LED negative terminal and the MOSFET Source pin is connected to ground.
*
* V1.2 Additions:
* control by normal ON/OFF switch
* The sketch is now optimized for integration in an existing house wiring situation, Where a standard light switch can be used to control
* the dimmer. Just toggling the switch will light the LED-(strip) smooth to 100% level or back to 0% when turning the light off.
* By a short ON-OFF switch-pulse the LED will dim to the last set dim level (when it was OFF) or dim to 0% when the LED was on.
* Setting a new target dim level can be done by keeping the switch on until it reaches the desired dim-level and the switch OFF again.
* Now the LED will stay on keeping the dim level.
* In all situations your home automation controller will be informed on the changing situations and off course can override the switch situation
*
* This sketch controls 2 LED-(strips) but can be easily extended by adding a LEDS entry to the led array (on line 70)
* The dim level can be set linear i.s.o. logarithmic (for your eyes this will look more linear)
*
* http://www.mysensors.org/build/dimmer
*/
#define MY_RADIO_NRF24
#include <SPI.h>
#include <MySensors.h>
#include <Bounce2.h>
#include <math.h>
#define LED1_PIN 6 // Arduino pin attached to MOSFET Gate pin
#define SW1_PIN 4
#define LED2_PIN 3 // Arduino pin attached to MOSFET Gate pin
#define SW2_PIN 2
#define MYS_INIT_DELAY 500
#define FADE_DELAY 10 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
enum DIMCURVES {
DIM_LINEAR = 0, // Normal linear curve
DIM_LINEAR_INV, // Inverted linear curve
DIM_LOGARITHMIC, // Normal logarithmic curve
DIM_LOGARITHMIC_INV, // Inverted logarithmic curve
DIM_CUSTOM // Define your own dimming curve
};
struct LEDS {
int currentLevel; // Current dim level
int toLevel; // Level to dim to
Bounce debouncer;
int LedPin;
int SwitchPin;
byte switchValue;
int savedLevel; // level to dim to when on is pressed
int switchCount;
bool ignoreNextSw; // if true ignore next OFF switch (was overriden by controller in ON state)
DIMCURVES dimcurve; // Set the dim curve mode (linear, logarithmic, inverted, custom)
MyMessage dimmerMsg;
MyMessage lightMsg;
};
LEDS led[] = {
{0, 0, Bounce(), LED1_PIN, SW1_PIN, 0, 100, 0, false, DIM_LINEAR_INV, MyMessage(0, V_DIMMER), MyMessage(0, V_LIGHT)},
{0, 0, Bounce(), LED2_PIN, SW2_PIN, 0, 100, 0, false, DIM_CUSTOM, MyMessage(1, V_DIMMER), MyMessage(1, V_LIGHT)}
};
#define MAXLED (sizeof(led)/sizeof(LEDS))
/***
* Dimmable LED initialization method
*/
void setup()
{
// Switch off all leds
for (byte id = 0; id < MAXLED; id++) {
pinMode(led[id].LedPin, OUTPUT);
setLedLevel(id);
}
// Register the LED Dimmable Light with the gateway
for (byte id = 0; id < MAXLED; id++) {
pinMode(led[id].SwitchPin, INPUT);
// Activate internal pull-up
digitalWrite(led[id].SwitchPin, HIGH);
present( id, S_DIMMER );
delay( MYS_INIT_DELAY );
// Pull the gateway's current dim level - restore light level upon sendor node power-up
request( id, V_DIMMER );
delay( MYS_INIT_DELAY );
// After setting up the button, setup debouncer
led[id].debouncer.attach(led[id].SwitchPin);
led[id].debouncer.interval(5);
}
sendSketchInfo("1.2", "LedStripSwitch");
}
/***
* Dimmable LED main processing loop
*/
void loop()
{
for (byte id = 0; id < MAXLED; id++) {
// If target level is not reached fade a little bit more
if (led[id].currentLevel != led[id].toLevel) {
led[id].currentLevel += ((led[id].toLevel - led[id].currentLevel ) < 0 ? -1 : 1);
setLedLevel(id);
}
// Check debounced button
led[id].debouncer.update();
byte switchValue = led[id].debouncer.read() ? 0 : 1; // Inverted signal
// Button change detected
if (led[id].switchValue != switchValue) {
Serial.print (F("Switch "));
Serial.println (switchValue);
led[id].switchValue = switchValue;
// If key released switch on when off or off when on --> when we where fading (above 100 steps) this is the end state
// When we just left the button (> 500) we now turning the lights off again
if (!switchValue && !led[id].ignoreNextSw) {
if (led[id].switchCount <= 100 || led[id].switchCount > 500) {
led[id].toLevel = (led[id].currentLevel ? 0 : led[id].savedLevel);
} else {
led[id].savedLevel = led[id].toLevel; // Store new saved level
}
// Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
send(led[id].lightMsg.set(led[id].toLevel > 0 ? 1 : 0));
send(led[id].dimmerMsg.set(led[id].toLevel) );
}
led[id].ignoreNextSw = false;
led[id].switchCount = 0;
} else if (switchValue && led[id].switchCount <= 500) {
// Keep counting until we reached 500 (@ 500 we asume we are in switch ON / OFF mode)
led[id].switchCount++;
// So this in not just a switch on (or off) but a new target led level key press
if (led[id].switchCount > 100) {
// Smooth led level increment, until the user found his/here desired dim lever
if ((led[id].switchCount % 3) == 0) {
// Stop increasing led level @ 100%
if (led[id].currentLevel < 100) {
if (led[id].currentLevel == 99) {
// Inform the gateway we've reached 100%
send(led[id].lightMsg.set(1));
send(led[id].dimmerMsg.set(100));
}
led[id].currentLevel++;
led[id].toLevel = led[id].currentLevel;
setLedLevel(id);
}
}
}
}
}
// Wait FADE_DELAY ms to smooth the dim level adjustments
wait(FADE_DELAY);
}
void incomingMessage(const MyMessage &message) {
if (message.type == V_LIGHT || message.type == V_DIMMER) {
byte id = (message.sensor % MAXLED);
// Retrieve the power or dim level from the incoming request message
// if this is a V_LIGHT variable update [0 == off, 1 == on] use savedLevel
int requestedLevel = ( message.type == V_LIGHT ? led[id].savedLevel * atoi( message.data ) : atoi( message.data ) );
if (requestedLevel > 0) {
// Store as lastLevel
led[id].savedLevel = requestedLevel;
}
// Make sure the new level is between 0 - 100
led[id].toLevel = (requestedLevel >= 0 ? min(requestedLevel, 100) : 0);
Serial.print(F("Changing node: "));
Serial.print( id );
Serial.print(F(", from: "));
Serial.print( led[id].currentLevel );
Serial.print(F("%, to: "));
Serial.print( requestedLevel );
Serial.println(F("%"));
// Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
send(led[id].lightMsg.set(requestedLevel > 0 ? 1 : 0));
send(led[id].dimmerMsg.set(requestedLevel) );
// Ignore next OFF switch when switch is ON and controller switches LED to OFF state)
led[id].ignoreNextSw = (led[id].toLevel == 0 && led[id].SwitchPin);
}
}
void setLedLevel(byte id)
{
// Convert level 0% - 100% to logathimic OR linear PWM range of 0 to 255
switch (led[id].dimcurve)
{
case DIM_LINEAR:
// Normal linear curve
analogWrite(led[id].LedPin, (int)(led[id].currentLevel * 2.5));
break;
case DIM_LINEAR_INV:
// Inverted linear curve
analogWrite(led[id].LedPin, 255 - (int)(led[id].currentLevel * 2.5));
break;
case DIM_LOGARITHMIC:
// Normal logarithmic curve
analogWrite(led[id].LedPin, fscale( 0, 100, 0, 255, led[id].currentLevel, -2));
break;
case DIM_LOGARITHMIC_INV:
// Inverted logarithmic curve
analogWrite(led[id].LedPin, 255 - fscale( 0, 100, 0, 255, led[id].currentLevel, -2));
break;
case DIM_CUSTOM:
analogWrite(led[id].LedPin, 255 - led[id].currentLevel);
break;
}
}
/* fscale
Floating Point Autoscale Function V0.1
Paul Badger 2007
Modified from code by Greg Shakar
*/
float fscale( float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve)
{
float OriginalRange = 0;
float NewRange = 0;
float zeroRefCurVal = 0;
float normalizedCurVal = 0;
float rangedValue = 0;
boolean invFlag = 0;
// condition curve parameter
// limit range
if (curve > 10) curve = 10;
if (curve < -10) curve = -10;
curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output
curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function
// Check for out of range inputValues
if (inputValue < originalMin) {
inputValue = originalMin;
}
if (inputValue > originalMax) {
inputValue = originalMax;
}
// Zero Refference the values
OriginalRange = originalMax - originalMin;
if (newEnd > newBegin){
NewRange = newEnd - newBegin;
} else {
NewRange = newBegin - newEnd;
invFlag = 1;
}
zeroRefCurVal = inputValue - originalMin;
normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float
// Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine
if (originalMin > originalMax ) {
return 0;
}
if (invFlag == 0) {
rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;
} else { // invert the ranges
rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
}
return rangedValue;
}```