@ksga
well i suggest you use google for this (the trafo). Also your link provide schema and code not so bad as a start. also there is a module (the Bluetooth classs) that set the power output from a literal in %. This is exactly what you need to bind it to Mysensor lib...
this is what i found on ebay Example link
This trafo does not provide much power but it is small and maybe sufficiënt for powering the arduino.
There is one catch when using a trafo : it introduce a phase shift so you must provide e methode (i believe a fix constant will do in most cases ) to trim the "offset" of the zero crossing.
As i am not a specialist on mysensors internal structure but for a atmega328p (uno) TCCR1A is used inseverall places ,for analog write Altsoftserial (RS485) etc. So you must be sure not to re-use the timer it will behave strange. Same is for the attachInterrupt function it is used in hwSleep function. As there are only 2 HW irq's you must choose the "right" one in most designs i believe irq 1 is used for the NRF24l01 /RFM69 so choose the other one on your mcu . For all these reasons i believe it will take many hours off testing to get the dimmer "glitch" free.
I believe for this resons it is better to offload the mcu and use a dedicated chip/mcu when you want to use Mysensors in your dimmer.
Posts made by stedew
-
RE: Help needed - SSR switch / SCR dimmer
-
RE: Help needed - SSR switch / SCR dimmer
@ksga
idd the bridge is not needed because the H1AA1 has two antiparrallel diodes.
As i said before the heat is a function I³*R. So yes, these resistors will get very hot (1W consumption @ 240V in total) It is ilmho not a good idea to use it like this given the fact that you get a few resistors in your circuit that always consume 1W even when the dimmer is off (and the resistors get very hot when you use a 1/2w type)
Yust imagine you consume 8760W every year yust to know the zero crossing.. -
RE: Help needed - SSR switch / SCR dimmer
@ksga
For the R1 R2 it is easy P = I² * R so for 240v rms this gives 8mA² * 30000 gives 1.92W! this wil give you a constant energy loss off 2W only to know the zero crossing (even when the light is out). Keep the old dimmer with the filament bulbs you will save energy
Possible the circuit is designed for 120VAC then you still need at least 1/2watt resistor (and 1W powerloss)
When you google a little i find combinations that use a transformer for the zero crossing.
Also the circuit here on instructables can help you
integrate this in the switch example is not a real good idea. Build the code for the zero crossing and dimming (firing triac) preferable in a seperate module /code block without the mysensors overhead. maybe you find some clues where you got the schema.
When you can succesfully dim on/off the lamp with your code then you can start thinking to glue it on the Mysensor lib(s)
I didn't search the forum here but i can imagine that building a interrupt driven zero crossing dimmer is a real challence. Particulary when it has to co-operate with the mysensor library...
I hope this helps
Regards ,
Stefan -
RE: Alternative to ArduinoIDE
@andrew
Hello Andrew, as Anticimex already answered also other IDE's are possible (Atmel Studio with a arduino plugin seems to work) Atom, and others I use the Eclipse + plugin solution and are happy with it. It is really a powerfull solution with many configuration options. I had a few discussions with the maintainer of sloeber (Jantje) and in general i made a few observations that summerize yours: lsee discussions on github
The problem for cpp is that you have to declare the prototypes because you lose the confort from the ino suffix.
Regards ,
Stefan -
RE: Esp8266 with wifi off
Tnx spot on
Before i measure 88mA and now ~ 30mA. In reality the profit (% saving) will be even higher. The test setup is with all node mcu hardware so there will definitly be a higher gain with a "bare" esp.
As for some may ask: why use a esp (nodeMCU) as a arduino?
-"Solid" Integrated 3v3 regulator
-Good RF design(shielding)
-USB RS232 interface
-High processing power (if needed).-I could not get the wifi gateway rock solid (compared to the RS232) .
From the moment domoticz disconnect (or the ESP lost connection) there was no communication anymore without an intervention to domoticz.Regards,
Stefan. -
Esp8266 with wifi off
Hello,
I have a small question and maybe someone else already knows the answer.
For testing i want to use a esp8266 (esp12 /nodemcu board) with a nrf24L01+) as a GW (serial).
I have this working but i want to shut down the WIFI completely what instruction i have to use for this?wifi_set_sleep_type(MODEM_SLEEP_T); delay(1); system_deep_sleep_set_option(MODEM_SLEEP_T);```
I don't know exactly and also while testing i was pinging the wrong ip so i got a little confused
What i basicly want to do is use the esp as a high performance GW/node.
So any suggest are welcome.
regards,
Stefan. -
RE: RS485 Speed and different routing possible?
haha,
I knew you gonne hijack this thread
As you answered the first question (more or less)
i was looking for a good test rig
long distance transmission lineI yust have to re-read the specs off the ADM isolator i think
So there is no possibility to route from node to node pitty.
Tnx for the answer anyway i will try the higher speed setting (57K6 or so)
Btw good write up about the RS485 setup on the home page it will defenetly speed up things (as i spend a few hours wit wrong setup)
Regards,
Stefan. -
RS485 Speed and different routing possible?
Hello someone tested a higher speed setting for the (new) RS485 communication in MS2.0.?
I think that 9600baud is really slow. That being sayed i have to admit it works like a charm.
-So when someone can confirm that this works also with long(er) lines and higher speed i would like to know.
In my setup i use on one side (GW + RPI) a ADM2483 (isolator) so that i have a galvanic separation and can play safely with the sensors. these are often near the life (electric cabinet/enclosures) on the other side (sensors /field) i use the MAX485 or an SN75HVD12DR RS485.
Second question: is it possible to send a message from one sensors to another on the same bus? Without the need to use code in the GW? to route the recaiver?
Regards,
Stefan. -
RE: Alternative to ArduinoIDE
@Daniel-Oliveira
Hello Daniel for what it's worth: Jantje posted a Fix in Github:
the selection of subfolders included to the path is not consistent with the Arduino IDEJust have to test it further
Regards,
Stefan -
RE: Best IDE to use for MySensors projects
Ok as i mentioned before:
At start nothing worked like i wanted in PIO then start reading....
Testing &implement all steps that seems to be needed (forums are top sometimes
Then changed computer (Wife...) and re-install everything from scratch.
And so i came to this exhaustive (wrong) list
So now the corrected one:PlatformIO:
1) Choose Board (here tested with UNO)
2) Choose Dir (only existing dir no create possible) (First make MKDIR BatteryPoweredSensor )
2) Choose Dir ( existing dir or create "BatteryPoweredSensor" )
3) Copy code file from Mysensors example dir to PlatformIO \src dir (right click open in explorer)
4) Enable Use development Version of PlatformIO (at the moment for PIO 3.0) in settings
~~ 5) Add PATH string variable in settings (Good explanation anyway)~~
~~6) Start cmd (Powershell in Windoze) from PlatformIO ~~
7) Execute the cmd >> platformio lib install 548 (For Mysensors 2.0 lib)
5 ) add 1 line to your platformio.ini config: lib_deps = MySensors (Dmnn that i try-ed already did not work then ?? to many modifs made i think)
6 ) Compile info: on my Laptop (slow one) compiles MySerialGw in 2sec!! (record for PIO)
7 ) Download to controllerAbout the other topics:
Refractoring is handy especialy when you use constants over severall files.
I am a chaotic person so i tend to forget one enum somewhere...
Goto declaration >> ok have to switch OS maybe not you/team to blame.
-Local history will try /need it (same problem as refractor point )
-upload_port very good one... will test it .--Improvements ?? Don't know i already own you a couple of beers i think.
I believe it is maybe handy to have a write up with screenshots "Adventures migration from Arduino to PIO".Regards,Stefan.
-
RE: Best IDE to use for MySensors projects
@ivankravets
Hello Mr IvankravetsOk birthday is done and bottles empty....
-Well When you compare to Arduino IDE vs PlatforIO is something slightly different:
Running the "BatteryPoweredSensor.ino" (Mysensors 2.0) example in Arduino 1.6
1)Load new Sketch "Examples">>Mysensors >> BatteryPoweredSensor
2)Compile >>will not work for all boards (due to INTERNAL is not defined for all AVR members )
3)Download to controllerPlatformIO: 1) Choose Board (here tested with UNO) 2) Choose Dir (only existing dir no create possible) (First make MKDIR BatteryPoweredSensor ) 3) Copy code file from Mysensors example dir to PlatformIO \src dir (right click open in explorer) 4) Enable Use development Version of PlatformIO (at the moment for PIO 3.0) in settings 5) Add PATH string variable in settings (Good explanation anyway) 6) Start cmd (Powershell in Windoze) from PlatformIO 7) Execute the cmd >> platformio lib install 548 (For Mysensors 2.0 lib) 8) Compile 9) Download to controller
-This being sayed for these additional steps you get something what is non existing in Arduino ide:
+AutoComplete variables /suggest with function prototypes
+Acces to all used code off the included library
+Compile in seconds-Still some questions also:
Is there a quick way to refractor over source files (not readed the manual)?
Goto declaration does not work (maybe my fault) Clang is installed however.
Local version control?
Specify wich serial port for upload (and not use the default first one)Tnx in advance,
Stefan. -
RE: Best IDE to use for MySensors projects
Hmm tnx for the clarification
I have a small party here (Wife birthday) so I will try to reproduce it later.
Otherwise the automatic script Divorse now will start...
regards,
Stefan. -
RE: Best IDE to use for MySensors projects
Hello Mr Kravets,
Can you give a hint/short explanation why Mysensors 2.0 Compiles ok in the upgraded version (the development branch). I can understand its maybe one off your internal secrets but i think that it can be benificial for others. I love a lot one off the "concurrent" IDE (Arduino Eclipse) and the (for my case) Problem is that it doesn't compile Mysensors 2.0. I assume with my limited knowledge and observations off the compiler errors the problems there are related..
-I Also tested the build and it took severall attempt to get it compiling. Unfotunatly i cannot reproduce it (Windows usr ) I had to fiddle severall times in the PATH var and settings and restart the IDE ....Anyway I hope that Arduino ide sees one day the Light and gets some inspiration on a project like this or even better start co-operating....
Good work !!! -
RE: Blindcontroller with PB local control
Again right.. but the class definition is in the BL_Control.h file (line 47) The reason not to put the logic is that i yust want some sceleton for this kind of physical controller now i don' t have to include write and reads in the class and i can re-use it maybe for a PB dimmer. That off the declaration with the pinmodes is a habbit from the plain C period and assembler adventures with the AVR. There i set my outputs to a safe state before setting the DDR(x) register. As far as i assume the DDR is only relevant when you read the input (or want to do a logic operation on the input/output state. And it is overkill to write this in C++. But for me i consider it as a good excercise. And no i don't have a question I only wanted it to publish so others can steal maybe a idea Cheers,
-
RE: Blindcontroller with PB local control
Hello TheoL i think you are right, but it is hard to copy/past a project to a forum. But why not i changed the post and now almost everybody can see how crapy code i write
Regards,
Stefan. -
RE: Blindcontroller with PB local control
This is part 2:
Under is the controller object it was (and is) for me an excercice how to make a modular c++ program
Al hw dependency is left out (except millis & Serial.print) everything should behave like defined on a different platform.
There is plenty room to improve this so shoot: be critic but fair wat i can improve (and how)File: "Bl_Control.cpp"
/* * Bl_Control.cpp * * Created on: 20 jul. 2016 * Author: Stefan * * * Setpoint controller up/down * Allows you to monitor and control a setpoint vs PV * 1 - use a local inputs byte to increase or decrease the position * 2 - send a setpoint/position request by a host * 3 - Set a Factor (gain) to change the ratio PV /SP * * * Version history: * 0.1 : build object class * 0.2 : Added a factor (gain) to allow a wider use and removed "magic numbers" in code * 0.3 : Fix for nasty RT-bug when gain gets higher then 131 >>integer overflow when multiply with BL_MAX_TIME_UP (250) * * * TODO: * :optimization use off variables * :implemnt auto teach sequence */ #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif #include "Bl_Control.h" Bl_Control::Bl_Control(){ _previoustMillis_inp_scan= millis();//init the scan clock when object is created _SP =BL_SP_MIN; //Current active SP _Remote_SP =BL_SP_MIN; //Last received SP received from the Host _Remote_CMD = t_BL_Cmd::BL_CMD_NONE;//Last received Command from the Host _Local_CMD = t_BL_Cmd::BL_CMD_NONE; ; //Last received Command from the inputs _Runtime = 0; //Time Controller is running _Error =0; //Module in error _PV =0; //Global internall Process_Value (PV) aka the actual (or estimated) position off the blind _ErrRunTmr =0; _Error=0; _tmrLocalCmddwn =t_BL_Cmd::BL_CMD_NONE; _tmrLocalCmdup =t_BL_Cmd::BL_CMD_NONE; _prev_rem_cmd= t_BL_Cmd::BL_CMD_NONE; _inputs=0; _ouputs=0; _RunCtrlCmd = t_BL_Cmd::BL_CMD_NONE; _RunCtrlprevLocCmd = t_BL_Cmd::BL_CMD_NONE; _Gain_PV =100; //Sets the controller to center gain (1/1)= 100% } /** * Get_Gain_PV : Returns the ratio (in %) _PV to _SP * inputs are : None * Chances : None * Returns : Factor (min) */ uint16_t Bl_Control::Get_Gain_PV(){ return _Gain_PV; } /** * Set_Gain_PV : Set the ratio _PV to _SP * inputs are : Newgain 10(%) min to 1000% max * Chances : _Gain_PV * Returns : None */ void Bl_Control::Set_Gain_PV (uint16_t NewGain){ if(_Gain_PV!=NewGain){ #if BL_DEBUG -1 Serial.print("N_Max_PV "); Serial.println(NewGain); #endif //We avoid float by multiply the result by 10 // 10 is 10% // 1000 is 1000% //TODO: Remove test //(Domoticz gives 1 to 100 and not 10 to 1000 NewGain = NewGain *10; if (NewGain >BL_PV_MAX ) {//Limit is 1000% NewGain = BL_PV_MAX ; }else if (NewGain > BL_PV_MIN ){ NewGain=(NewGain ); }else{ NewGain = (BL_PV_MIN ) ;//Limit is 10 } _Gain_PV=NewGain; #if BL_DEBUG -1 Serial.print("New_Gain: "); Serial.println(_Gain_PV,DEC ); #endif } } /** * bl_Process Main worker when called the period elapsed is evaluated if expired the internal routines * shall be executed * inputs are : None * * Chances : _previoustMillis_inp_scan (Time keeper) * : * Returns : None */ void Bl_Control::bl_Process (){ unsigned long currentMillis = millis(); if (currentMillis - _previoustMillis_inp_scan >= UPDATE_INPUTS_ms) { Update_Local_cmd(); Run_ctrl( ); _previoustMillis_inp_scan = currentMillis; } } /** * Update_Local_cmd - Evaluate the local input byte and update the _Local_CMD off the blind * inputs are : none * : (except the internal _inputs) * outputs are : none * : * Returns : _Local_CMD * * routine is called on a regular (timed)interval and manipulates _Local_CMD * The routine sets the cmd_state and stores the last command executed * 1° a Short (input)cmd_up/cmd_dwn gives a run to the direction requested (MAX/MIN) * 2° Long cmd_up/cmd_down gives a run state UP/DWN until release (tipping) * 3° cmd_up && cmd_dwn at same time : >> reset Error state * 4° A retrigger (when running to the max/min) >> stop is executed * */ uint8_t Bl_Control::Update_Local_cmd (void) { uint8_t tmp_cmd = _Local_CMD; //First test if there is a error reset request (both cmd_up && cmd_dwn active) if (((bitRead(_inputs, t_BL_InBits::INCR ) != 0 )&& (bitRead(_inputs, t_BL_InBits::DECR) !=0))) { _tmrLocalCmddwn =0;//Reset counters /Timers _tmrLocalCmdup = 0; _Local_CMD = t_BL_Cmd::BL_CMD_RST;//Store the last action _Error = false;// return _Local_CMD; } if (_Error) { return _Local_CMD; } // Blind up evaluation if (bitRead(_inputs,t_BL_InBits::INCR)) { if (_tmrLocalCmdup <= BL_T_Hold) { //Increase hold counter _tmrLocalCmdup++; tmp_cmd = t_BL_Cmd::BL_CMD_INC; //Sets a increase marker (tipping mode) if ( _Local_CMD == t_BL_Cmd::BL_CMD_UP) { //Repeated impulse command change to tipping mode _tmrLocalCmdup = BL_T_Hold; //set timer to holdlimit so we can stop at PB release } }else{ } } else { if ((_tmrLocalCmdup !=0) && (_tmrLocalCmdup < BL_T_Hold)){ // cmd_up is impulsed tmp_cmd = t_BL_Cmd::BL_CMD_UP; }else{ // button was hold longer then T_Hold (Tipping) but now released if (_tmrLocalCmdup >=BL_T_Hold) tmp_cmd = t_BL_Cmd::BL_CMD_STOP; } // When button is released reset the counter _tmrLocalCmdup =0; } // Blind Down evaluation if (bitRead(_inputs, t_BL_InBits::DECR )) { //st_tmrhld_Localup=0; // When we go down up is reset if (_tmrLocalCmddwn <= BL_T_Hold){ _tmrLocalCmddwn++; //Increase hold tmp_cmd = t_BL_Cmd::BL_CMD_DEC; if ( _Local_CMD == t_BL_Cmd::BL_CMD_DWN) {//Repeated impulse command change to tipping mode _tmrLocalCmddwn = BL_T_Hold; //set timer to holdlimit so we can stop at PB release } } } else { if ((_tmrLocalCmddwn !=0) && (_tmrLocalCmddwn < BL_T_Hold)){ // cmd_dwn is impulsed tmp_cmd = t_BL_Cmd::BL_CMD_DWN; }else{ // button was hold longer then T_Hold (tipping) but now released >>release Tip if (_tmrLocalCmddwn >=BL_T_Hold) tmp_cmd = t_BL_Cmd::BL_CMD_STOP; } // When button is released reset the counter _tmrLocalCmddwn =0; } if (tmp_cmd != _Local_CMD) { _Local_CMD = tmp_cmd; } return _Local_CMD; } /** * bl_GetOutputs Returns the current output bits to the caller * inputs are : None * * Chances : None * : * Returns : Output bits */ uint8_t Bl_Control::bl_GetOutputs (void) { return _ouputs; } /** * UpdateRemote_cmd - Evaluate the messages from the host (here domoticsz) * inputs are : MyMessage * * Chances : _Remote_SP, * : * Returns : remote_Commandstate * * routine is called when a message from the host is received * The routine sets the cmd_stat and stores the last command if changed * The routine interprets the message and send a open/close or run to new setpoint */ uint8_t Bl_Control::UpdateRemote_cmd (uint8_t Sp, uint8_t cmd_Type ) { uint8_t tmp_cmd= _Remote_CMD;//Current command uint8_t tmp_SP ;// Current Setpoint tmp_SP = _Remote_SP;//Store the current SP if (bitRead(cmd_Type ,0)) { // This is a SP change request if (_Remote_SP != Sp) {//Is SP from host different to current one? #if BL_DEBUG -1 Serial.println("BL_RM"); Serial.print("New SP: "); Serial.println(val); #endif tmp_SP = Sp; //set SP to the requested value tmp_cmd = BL_CMD_RUN; }else {//Nothing to do except change local static tmp_cmd = BL_CMD_NONE;//reception off same as previous SP } } else if (bitRead(cmd_Type ,1)|| bitRead(cmd_Type ,2)) {//Position request (full open / full closed) if (bitRead(cmd_Type ,1)) { //I Use a inverted blind on the GUI if (_Remote_CMD ==BL_CMD_DWN ) {//Re-fire in Run will trigger a stop tmp_cmd = BL_CMD_STOP;//Second push to full position >> stop #if BL_DEBUG -1 Serial.println("BL STP"); #endif }else{ tmp_SP = BL_SP_MIN ;//adjust SP to min (close) tmp_cmd= BL_CMD_DWN; #if BL_DEBUG -1 Serial.println("BL_DWN"); #endif } } else { if (_Remote_CMD ==BL_CMD_UP) { tmp_cmd = BL_CMD_STOP;//Second push to full position >> stop #if BL_DEBUG -1 Serial.println("BL STP"); #endif } else { tmp_SP = BL_SP_MAX ;//adjust SP to max tmp_cmd= BL_CMD_UP; #if BL_DEBUG -1 Serial.println("BL_UP"); #endif } } } if (_Remote_CMD == tmp_cmd){ if (_Remote_SP != tmp_SP) { _Remote_SP = tmp_SP; //Overwrite back (modified) SP to caller _Remote_CMD = BL_CMD_RUN; //Set Run State to start return _Remote_CMD; } else { return BL_CMD_NONE; //Nothing changed } }else{ _Remote_SP = tmp_SP; //write back (modified) SP to caller _Remote_CMD = tmp_cmd; return _Remote_CMD; } } /** * SetInputs : changes the local inputbits (input command word) * inputs are : inc * : dec * : RunCurrent * * outputs are : none (manipulates the internal input byte) * Returns : none * * call this routine to reflect input changes to the ( internal )input controller */ void Bl_Control::bl_SetInputs(uint8_t inc , uint8_t dec, uint8_t RunCurrent ){ if (inc) bitSet(_inputs,t_BL_InBits::INCR); else bitClear(_inputs,t_BL_InBits::INCR); if (dec) bitSet(_inputs,t_BL_InBits::DECR); else bitClear(_inputs,t_BL_InBits::DECR); if (RunCurrent) bitSet(_inputs,t_BL_InBits::CURSNS); else bitClear(_inputs,t_BL_InBits::CURSNS); } /** * bl_RunErrorLed :Give some feedback for the user * inputs are : inc * : dec * : RunCurrent * * outputs are : none * : * Returns : State for the error/run Led * * call this routine for getting the led state (In Run slow blink / In error fast blink) * */ uint8_t Bl_Control::bl_RunErrorLed(void){ if (_Error){ if (bitRead(_ErrRunTmr,1)){ return true; }else{ return false; } }else{ if ((bitRead(_ouputs,t_BL_OutBits::BL_RN_UP))||bitRead(_ouputs,t_BL_OutBits::BL_RN_DWN) ) { if (bitRead(_Runtime,2)){ return true; }else{ return false; } return true; }else { if (_ErrRunTmr) _ErrRunTmr=0; return false; } } } /** * Run_ctrl - main worker controls the movement off the blind * inputs are : _Error, _SP, _PV (internal) * : * outputs are : none * : * Returns : _ouputs (for I/0) * * routine is called on a regular (timed)interval and is controlled by the inputs byte(s) * Commands are stored and executed if a change occurs compared to previous (call) * Also an error will cause a stop immediately * Total runtime is controlled and generates a error if exceeded >> in Error no remote commands are accepted only the local reset cmd * */ uint8_t Bl_Control::Run_ctrl (void){ uint32_t tmp_l1 = 0;//Local scratch var //First Test for a pending error if (_Error ) { _RunCtrlCmd=BL_RN_ERR; _Runtime =0;//Stop internal timer if (_ErrRunTmr == 0xff) { _ErrRunTmr = 1; } else { _ErrRunTmr++; } return _RunCtrlCmd;//Exit here no need to continue }else{ _ErrRunTmr=0; } //TODO: interlocking the remote /local should be optimized //No errors: evaluate witch command must be executed check for (new) local/remote command if (_Local_CMD !=_RunCtrlprevLocCmd ) { //Local command different from current run state store in _RunCtrlCmd _RunCtrlCmd = _Local_CMD; //Make the new stat the active one #if BL_DEBUG-1 Serial.print("BL_LC"); Serial.println(_RunCtrlCmd); #endif } else if (_Remote_CMD != _prev_rem_cmd) { #if BL_DEBUG-1 Serial.println("BL_RM"); #endif _RunCtrlCmd =_Remote_CMD;//copy the remote cmd to local }else{ //Leave it there is no new cmd } //Setpoint manipulator/Controller (depends on (new)input command switch (_RunCtrlCmd) { case BL_CMD_STOP: _SP = _PV;//Assign the actual PV to the internal SP break; case BL_CMD_INC ://increase Setpoint //only increase if SP is smaller then max PV if (_SP < (_Gain_PV)){ _SP++ ; if (_Runtime ==0) _Runtime =1; } break; case BL_CMD_UP://Setpoint to max if (_SP != _Gain_PV) { _SP = _Gain_PV ; if (_Runtime ==0) _Runtime =1; //Run ...Run } break; case BL_CMD_DEC ://Setpoint decrease (tipping) if (_SP != BL_SP_MIN){ if(_SP > (BL_SP_MIN) ){ _SP-- ; if (_Runtime ==0) _Runtime =1; } #if BL_DEBUG-1 Serial.print("DSP: "); Serial.println(_SP,DEC ); #endif } break; case BL_CMD_DWN ://Setpoint to min if (_SP != BL_SP_MIN) { _SP = BL_SP_MIN; if (_Runtime ==0) _Runtime =1; } break; case BL_CMD_RUN : //Setpoint received from host tmp_l1 =(_Remote_SP * _Gain_PV /BL_SP_MAX); //First calculate the scaled setpoint from the host if (_SP != tmp_l1){ //is this a different setpoint ? _SP = tmp_l1; #if BL_DEBUG-1 Serial.print("Sp: "); Serial.println(_SP,DEC); Serial.print("_PV: "); Serial.println(_PV,DEC ); #endif if (_Runtime ==0) _Runtime =1; } break; default: break; } //Position (PV) Generator there is no feedback position so it is simulated by counters/timers if (_SP ==( _PV) ){ bitClear(_ouputs, t_BL_OutBits::BL_RN_DWN); bitClear(_ouputs, t_BL_OutBits::BL_RN_UP); _Runtime =0;//Stop }else{ if ((_SP ) > (_PV) ){ bitClear(_ouputs, t_BL_OutBits::BL_RN_DWN); bitSet(_ouputs, t_BL_OutBits::BL_RN_UP); if ((_PV < _Gain_PV) && (_Runtime !=0))_PV++; }else{ //(_SP < _PV) bitClear(_ouputs, t_BL_OutBits::BL_RN_UP); bitSet(_ouputs, t_BL_OutBits::BL_RN_DWN); if (_PV>=BL_SP_MIN) _PV--; } } // Feedback that there is still current flowing if (bitRead(_inputs,t_BL_InBits::CURSNS )){ // We still are driving the outputs increase run time if (_Runtime){ // FIX 0.3 : the line beneath uses a cast (uint32_t) on a constants omitting this will give you a few hours joy... tmp_l1 =(uint32_t)BL_MAX_TIME_UP * _Gain_PV / (uint32_t)BL_SP_MAX ; //First calculate the max (scaled) Run time #if BL_DEBUG -1 if (_Runtime ==2) { Serial.print("Max_PV: "); Serial.println(tmp_l1,DEC); } #endif if ( _Runtime < tmp_l1)_Runtime ++; //If not overtime increase timer #if BL_DEBUG -1 Serial.print("RT: "); Serial.println(_Runtime,DEC); Serial.print("PV: "); Serial.println(_PV,DEC); #endif } }else{ //Current is dropped >> Motor off or (in this case) end limit reached if (( bitRead(_ouputs, t_BL_OutBits::BL_RN_UP ) ||bitRead(_ouputs, t_BL_OutBits::BL_RN_DWN )) && (_Runtime>WAITFORCURRENT) ) { //Todo: when testing this with feedback maybe this can be optimized to _PV = _SP; (as this will probably be true ) //When the current is gone we have reached a end limit if ( bitRead(_ouputs, t_BL_OutBits::BL_RN_UP )){ bitClear(_ouputs, t_BL_OutBits::BL_RN_UP); _PV = _Gain_PV;//Reached the Max limit ...inform the host } if ( bitRead(_ouputs, t_BL_OutBits::BL_RN_DWN )){ bitClear(_ouputs, t_BL_OutBits::BL_RN_DWN); _PV = BL_SP_MIN;//Reached the min limit ...inform the host } //The current is gone but still driving UP/DOWN stop it (should be redundant here) bitClear(_ouputs, t_BL_OutBits::BL_RN_DWN); bitClear(_ouputs, t_BL_OutBits::BL_RN_UP); } } // Guard the max run time (Up/down time) if (_Runtime){ // FIX 0.3 : the line beneath uses a cast (uint32_t) on a constants omitting this will give you a few hours joy... tmp_l1 = (uint32_t) BL_MAX_TIME_UP *_Gain_PV / (uint32_t)BL_SP_MAX;//First calculate the max (scaled) Run time if ( _Runtime >= tmp_l1) { bitClear(_ouputs, t_BL_OutBits::BL_RN_DWN); //Overrun (blokking?) >> stop bitClear(_ouputs, t_BL_OutBits::BL_RN_UP); bitSet(_ouputs, t_BL_OutBits::BL_RN_ERR); _Error = true; #if BL_DEBUG-1 Serial.print("RT: "); Serial.print(_Runtime); Serial.print(" HL: "); Serial.print(tmp_l1,DEC); Serial.print(" G: "); Serial.print(_Gain_PV); Serial.println(" TIME_OUT "); #endif } } if (_Local_CMD !=_RunCtrlprevLocCmd ) { //Update the command switcher for next entry _RunCtrlprevLocCmd = _Local_CMD; }else if (_Remote_CMD !=_prev_rem_cmd ){ _prev_rem_cmd = _Remote_CMD; } return _ouputs;// return the Run_Result } /** * Get_PV : Returns the current ProcessValue (actual state) or feedback in % * inputs are : None * Changes : None * : * Returns : _PV * */ uint8_t Bl_Control::Get_PV (void){ return ((_PV*BL_SP_MAX)/_Gain_PV); }
At last the header File "Bl_Control.h"
// - function definitions (prototypes) // - include files // - extern variable definitions // In the appropriate section #ifndef _BL_Control_H_ #define _BL_Control_H_ #include "Arduino.h" //add your includes for the project BlindController here #include <inttypes.h> //end of add your includes here //add your function definitions for the project BlindController here #define BL_DEBUG 1 //Enable/disable debugging msg (to serial) #define UPDATE_INPUTS_ms 50UL // scan time inputs for change #define WAITFORCURRENT 3 //Allow the current to come up when outputs activate #define BL_T_Hold 5 // This is the number off scans before a button is considered as hold (Tipping) #define BL_SP_MIN 0x00 // SP_LL no comment.... #define BL_SP_MAX 100 // SP_H This value is the value considered as 100% output #define BL_MAX_TIME_UP 250 //With a scan time off 50mSec the this give only 12Sec (1000mSec/50 * t_Scan_SeC < 0xFF) //on the other hand there is also a factor ( #define BL_PV_MIN 10 // Min gain percentage (10%) #define BL_PV_MAX 1000UL // Min gain percentage (1000%) #if BL_MAX_TIME_UP <= BL_SP_MAX //When changing parameters test if the SP is reachable without error #error "Attention !! you can't reach the max allowed SP val in one run with this setting!" #endif typedef enum BL_OutBits { BL_RN_UP, BL_RN_DWN, BL_RN_ERR}t_BL_OutBits; typedef enum BL_Cmd {BL_CMD_NONE, BL_CMD_STOP,BL_CMD_INC, BL_CMD_UP, BL_CMD_DEC ,BL_CMD_DWN,BL_CMD_RST ,BL_CMD_RUN} t_BL_Cmd ; typedef enum BL_InBits{ INCR, DECR, CURSNS}t_BL_InBits; class Bl_Control { public: // Create an instance of the BlindController Bl_Control(); // call this to run the timers void bl_Process (void); //Get the outputbits uint8_t bl_GetOutputs (void); //Update info from the host (updates the remote cmd bits) uint8_t UpdateRemote_cmd (uint8_t Sp, uint8_t cmd_Type ); //Set the inputs void bl_SetInputs (uint8_t inc , uint8_t dec, uint8_t RunCurrent ); uint8_t bl_RunErrorLed (void); uint8_t Get_PV (void); uint16_t Get_Gain_PV (); void Set_Gain_PV (uint16_t fakt); private: //SP and PV updater uint8_t Run_ctrl (void); // evaluate the inputcmd (timers) uint8_t Update_Local_cmd (void); protected: uint8_t _tmrLocalCmdup; //Timer off the PB UP uint8_t _tmrLocalCmddwn; //Timer off the PB DWN uint8_t _ErrRunTmr; //Timer off the error/Run uint8_t _RunCtrlCmd; //the active command off Controller uint8_t _RunCtrlprevLocCmd ; //Store the previous local state uint8_t _prev_rem_cmd; //Store the previous state at end off routine uint8_t _inputs; //InputBits uint8_t _ouputs; //OutputBits //timer logic to schedule updates ,cmd ,inputs,... unsigned long _previoustMillis_inp_scan ; uint8_t _Remote_SP; //Last received SP received from the Host uint8_t _Remote_CMD ; //Last received Command from the Host uint8_t _Local_CMD ; //Last received Command from the inputs uint16_t _Runtime ; //Time Controller is running uint16_t _SP ; //internal Setpoint uint16_t _PV; //Global Process_Value (PV) aka the actual (or estimated) position uint8_t _Error; //Module in error uint16_t _Gain_PV ; //Factor for _PV to reach the setpoint (in %) }; //Do not add code below this line #endif /* _BL_Control_H_ */
-
Blindcontroller with PB local control
Hello,
This sketch can be used for control a blind (local + remote) it is working but there is still room for improvement ... to say the least
Any suggestions remarks are welcome
heu it isnottested in arduino dev (now it is 2016/08/03) (i use eclipse arduino IDE)Update 2016/08/03:
insert files as requested by TheoL (and removed the ZIP file
**ATTENTION ** i could not make it in one post so you need also part 2 !!This is the main sketch (and corrected smal bug)
"Rfm69_BlindController.ino"
// Do not remove the include below #include "Rfm69_BlindController.h" #include "Bl_Control.h" /* BlindController for MySensors (or any other local/remote control ) This is a adaption off this sketch (garage door control) original is @ https://forum.mysensors.org/topic/4059/automated-garage-door/21 from user https://forum.mysensors.org/user/dbemowsk However not much is still in it July 20,2016 This will allow the MySensors gateway to monitor and control your blinds. This sketch monitors the actual position of the blind(s). It CAN use a sens input to detect current flowing (true/false) when the blind is running and current stops (current gets zero) we know the demanded position limit is reached, in the required direction (hard limit up/down). This sketch features the following: Allows you to monitor and control the blind position and return it's status based on the following: 1 - use two local inputs (buttons) to increase or decrease the position 2 - sending a setpoint/position request by a host (Mysensor here) 3 - Send a Factor (gain) to fine tune the time run up/down) PARTS LIST:(for 2 blinds) Moteino 4 3 or 5v relay 4 2N3904 transistor for relay 4 1k resistor 2 2k7 Resistor (for Led) 2 Led (error /run) HW CONFIG; (here moteino) Relay UP D5 (Blind1) Relay Down D6 (Blind1) Error/Run Led D7 (Blind1) InputUP D14 (Blind1) InputDown D15 (Blind1) Currentsense D16 (Blind1) Relay UP D3 (Blind2) Relay Down D4 (Blind2) Error/Run Led D17 (Blind2) InputUP D18 (Blind2) InputDown D19 (Blind2) Currentsense A6 (Blind2) Version history: 0.1 : Refractor original source (garage opener see ref) 0.2 : Build original concept without object 0.3 : Rebuil d with object class 0.4 : Added a factor (gain) to allow a wider use and removed "magic numbers" in code 0.5 : Added code for retrieving factor from EEPROM : added fix for nasty RT-bug when gain gets higher then 131 (integer overflow) */ #include <MyTransportRFM69.h> #include <MyHwATMega328.h> #include <MySensor.h> //#include <SPI.h> #define SKETCH_NAME "BlindController" #define SKETCH_VERSION "0.4" #define NODE_ID 85 //Define The node <> 0 (i don't want a auto assignment see setup @mySensors) #define CHILD_ID_SP_BL1 52 //Here we receive the setpoint #define CHILD_ID_GAIN_BL1 53 //This is the gain (value from 10 to 1000%!) #define CHILD_ID_SP_BL2 55 //Here we receive the setpoint #define CHILD_ID_GAIN_BL2 56 //This is the gain (value from 10 to 1000%!) #define EPROM_GAIN_BL1 1 //This is the location where the factor is stored (Blind1) //After a power failure this value will be restored #define EPROM_GAIN_BL2 3 //This is the location where the factor is stored (Blind2) #define DI_BL1_UP 14 //Pin used for command up #define DI_BL1_DWN 15 //Pin used for command Down #define AI_BL1_SENS 16 //Pin used Sensing the current (Yes/no) #define DO_BL1_MOTOR_UP 5 //Pin activate relay up #define DO_BL1_MOTOR_DWN 6 //Pin activate Relay Down #define DO_BL1_ERR_RUN 7 //Pin activate Run/error #define DI_BL2_UP 18 //Pin used for command up #define DI_BL2_DWN 19 //Pin used for command Down #define AI_BL2_SENS A6 //Pin used Sensing the current (Yes/no) #define DO_BL2_MOTOR_UP 3 //Pin activate relay up #define DO_BL2_MOTOR_DWN 4 //Pin activate Relay Down #define DO_BL2_ERR_RUN 17 //Pin activate Run/error #define MOTOR_ON 0 // GPIO value to write to turn on attached relay #define MOTOR_OFF 1 // GPIO value to write to turn off attached relay #define DEBUG_BLINDCONTROLLER 0 // Set to non zero for debugging // new V_TEXT variable type (development 20150905) //const int V_TEXT = 47 ; // new S_INFO sensor type (development 20150905) //const int S_INFO = 36 ; //Some timer logic to do updates on the inputs unsigned long bl_previoustMillis_inp_scan =0; MyMessage msg(CHILD_ID_SP_BL1, V_PERCENTAGE);// global response object MyTransportRFM69 transport; //Attention most users will use a NRF here!! // Hardware profile MyHwATMega328 hw; MySensor gw(transport,hw); //MyMessage msgStatus(CHILD_ID_STATUS, V_TEXT); Bl_Control blind1,blind2; //Handle to controller Instance /** * Function Prototypes */ // hmm.. seems not needed in Arduino /** * setup - Initialize the HW */ void setup() { //BLIND1 //initialize the inputs Blind1 pinMode(DI_BL1_UP, INPUT_PULLUP); pinMode(DI_BL1_DWN, INPUT_PULLUP); pinMode(AI_BL1_SENS,INPUT_PULLUP); //Set outputs to safe state and init digitalWrite( DO_BL1_MOTOR_UP,MOTOR_OFF); digitalWrite( DO_BL1_MOTOR_DWN,MOTOR_OFF); digitalWrite(DO_BL1_ERR_RUN ,MOTOR_OFF); pinMode(DO_BL1_MOTOR_UP, OUTPUT); pinMode(DO_BL1_MOTOR_DWN, OUTPUT); pinMode(DO_BL1_ERR_RUN, OUTPUT); //BLIND2 //TODO: Test extra controller pinMode(DI_BL2_UP, INPUT_PULLUP); pinMode(DI_BL2_DWN, INPUT_PULLUP); //pinMode(AI_BL2_SENS,INPUT_PULLUP); //Set outputs to safe state and init digitalWrite( DO_BL2_MOTOR_UP,MOTOR_OFF); digitalWrite( DO_BL2_MOTOR_DWN,MOTOR_OFF); digitalWrite(DO_BL2_ERR_RUN ,MOTOR_OFF); pinMode(DO_BL2_MOTOR_UP, OUTPUT); pinMode(DO_BL2_MOTOR_DWN, OUTPUT); pinMode(DO_BL2_ERR_RUN, OUTPUT); #if NODE_ID gw.begin( incomingMessage, NODE_ID,false); //No repeater NODE_ID is defined #else gw.begin( incomingMessage); //No NODE_ID auto from GW (Host) will give you one #endif gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION ); // Register the blind to the gateway gw.present( CHILD_ID_SP_BL1, S_DIMMER,"Position" ); gw.present(CHILD_ID_GAIN_BL1, S_DIMMER, "Gain"); gw.present( CHILD_ID_SP_BL2, S_DIMMER,"Blind 2 Pos" ); gw.present(CHILD_ID_GAIN_BL2, S_DIMMER, "Blind 2 Gain"); //init the scan clock bl_previoustMillis_inp_scan = millis()+1000; //Give a offset from the current moment (1000msec) to complete the setup //Restore from local EEprom the factor/gain int Gain=gw.loadState(EPROM_GAIN_BL1); //Get the gain from the EEPROM Gain = highByte(Gain) ; Gain|= lowByte( gw.loadState(EPROM_GAIN_BL1+1)); //Get the gain from the EEPROM blind1.Set_Gain_PV((uint16_t ) Gain); //Store the gain in controller obj Blind1 msg.setSensor(CHILD_ID_GAIN_BL1); //Set startup gain to host msg.set(Gain); gw.send( msg); //send it to the host Gain=gw.loadState(EPROM_GAIN_BL2); //Get the gain from the EEPROM Gain = highByte(Gain); Gain|= lowByte( gw.loadState(EPROM_GAIN_BL2+1)); //Get the gain from the EEPROM blind2.Set_Gain_PV((uint16_t ) Gain); //Store the gain in controller obj Blind1 msg.setSensor(CHILD_ID_GAIN_BL2); //Set startup gain to host msg.set(Gain); gw.send( msg); //send it to the host // Pull the gateway's current Blind level - restore level upon sender node power-up gw.request( CHILD_ID_SP_BL1, V_DIMMER ); // Pull the gateway's current Blind level - restore level upon sender node power-up gw.request( CHILD_ID_SP_BL2, V_DIMMER ); } void tasks (){ uint8_t tmp_Current , tmp_Current2; uint8_t tmp_up, tmp_up2; uint8_t tmp_dwn , tmp_dwn2; static uint8_t st_PrevOutput_State =0; //Local memory only update when something static uint8_t st_PrevOutput_State2 =0; uint8_t tmp_CurrentOutput_State,tmp_CurrentOutput_State2; //Read local inputs blind1 tmp_up = digitalRead(DI_BL1_UP )==false; tmp_dwn = digitalRead(DI_BL1_DWN)==false; //TODO: Test proof of concept: tmp_Current =1; // digitalRead(t_BL_InBits::CURSNS)==false; //Read local inputs blind1 tmp_up2 = digitalRead(DI_BL2_UP )==false; tmp_dwn2 = digitalRead(DI_BL2_DWN)==false; tmp_Current2 =1; //tmp_Current2= analogRead(AI_BL2_SENS) > 100 ? 0 : 1; blind1.bl_SetInputs(tmp_up,tmp_dwn,tmp_Current); tmp_CurrentOutput_State =blind1.bl_GetOutputs(); blind2.bl_SetInputs(tmp_up2,tmp_dwn2,tmp_Current2); tmp_CurrentOutput_State2 = blind2.bl_GetOutputs(); // Somethings changed do actions if (st_PrevOutput_State != tmp_CurrentOutput_State){ if (bitRead(tmp_CurrentOutput_State, t_BL_OutBits::BL_RN_ERR )) { digitalWrite(DO_BL1_MOTOR_UP,MOTOR_OFF); digitalWrite(DO_BL1_MOTOR_DWN,MOTOR_OFF); digitalWrite(DO_BL1_ERR_RUN,MOTOR_ON); #if DEBUG_BLINDCONTROLLER Serial.println("RN_ERR"); #endif } if (bitRead(tmp_CurrentOutput_State, t_BL_OutBits::BL_RN_UP )) { digitalWrite(DO_BL1_MOTOR_UP,MOTOR_ON); digitalWrite(DO_BL1_MOTOR_DWN,MOTOR_OFF); #if DEBUG_BLINDCONTROLLER Serial.println("RN_U"); #endif }else{ digitalWrite(DO_BL1_MOTOR_UP,MOTOR_OFF); #if DEBUG_BLINDCONTROLLER Serial.println("RN_S1"); #endif } if (bitRead(tmp_CurrentOutput_State, t_BL_OutBits::BL_RN_DWN )) { digitalWrite(DO_BL1_MOTOR_UP,MOTOR_OFF); digitalWrite(DO_BL1_MOTOR_DWN,MOTOR_ON); #if DEBUG_BLINDCONTROLLER Serial.println("RN_D"); #endif }else{ digitalWrite(DO_BL1_MOTOR_DWN,MOTOR_OFF); #if DEBUG_BLINDCONTROLLER Serial.println("RN_S2"); #endif } st_PrevOutput_State = tmp_CurrentOutput_State; if (blind1.Get_PV() >100){ msg.setSensor(CHILD_ID_SP_BL1); msg.setType(V_PERCENTAGE); gw.send( msg.set(100) ); //Inform the host that we are on the max } else{ msg.setSensor(CHILD_ID_SP_BL1); msg.setType(V_PERCENTAGE); gw.send( msg.set(blind1.Get_PV()) ); } } // Somethings changed for blind2 do actions if (st_PrevOutput_State2 != tmp_CurrentOutput_State2){ if (bitRead(tmp_CurrentOutput_State2, t_BL_OutBits::BL_RN_ERR )) { digitalWrite(DO_BL2_MOTOR_UP,MOTOR_OFF); digitalWrite(DO_BL2_MOTOR_DWN,MOTOR_OFF); digitalWrite(DO_BL2_ERR_RUN,MOTOR_ON); #if DEBUG_BLINDCONTROLLER Serial.println("RNERR2"); #endif } if (bitRead(tmp_CurrentOutput_State2, t_BL_OutBits::BL_RN_UP )) { digitalWrite(DO_BL2_MOTOR_UP,MOTOR_ON); digitalWrite(DO_BL2_MOTOR_DWN,MOTOR_OFF); #if DEBUG_BLINDCONTROLLER Serial.println("RNU2"); #endif }else{ digitalWrite(DO_BL2_MOTOR_UP,MOTOR_OFF); #if DEBUG_BLINDCONTROLLER Serial.println("RNS12"); #endif } if (bitRead(tmp_CurrentOutput_State2, t_BL_OutBits::BL_RN_DWN )) { digitalWrite(DO_BL2_MOTOR_UP,MOTOR_OFF); digitalWrite(DO_BL2_MOTOR_DWN,MOTOR_ON); #if DEBUG_BLINDCONTROLLER Serial.println("RN_D2"); #endif }else{ digitalWrite(DO_BL2_MOTOR_DWN,MOTOR_OFF); #if DEBUG_BLINDCONTROLLER Serial.println("RNS2"); #endif } st_PrevOutput_State2 = tmp_CurrentOutput_State2; if (blind2.Get_PV() >100){ msg.setSensor(CHILD_ID_SP_BL2); msg.setType(V_PERCENTAGE); gw.send( msg.set(100) ); //Inform the host that we are on the max } else{ msg.setSensor(CHILD_ID_SP_BL2); msg.setType(V_PERCENTAGE); gw.send( msg.set(blind2.Get_PV()) ); } } //Update the eye candy (feedback) Blind1 if (blind1.bl_RunErrorLed() ){ digitalWrite(DO_BL1_ERR_RUN,MOTOR_ON); }else{ digitalWrite(DO_BL1_ERR_RUN,MOTOR_OFF); } //Update the eye candy (feedback) Blind2 if (blind2.bl_RunErrorLed() ){ digitalWrite(DO_BL2_ERR_RUN,MOTOR_ON); }else{ digitalWrite(DO_BL2_ERR_RUN,MOTOR_OFF); } } /** * loop - The main program loop */ void loop() { // Alway process incoming messages whenever possible gw.process(); blind1.bl_Process(); blind2.bl_Process(); tasks(); } /** * incomingMessage - Process the incoming messages * From the host */ void incomingMessage( const MyMessage &message ) { uint16_t tmp_Faktor; uint8_t New_sp =0; uint8_t New_Cmd=0; if (message.sensor ==CHILD_ID_SP_BL1 ) { if (message.type == V_DIMMER) { // This is a SP change request int val = message.getInt();//retrieve SP from message bitSet(New_Cmd,0); New_sp = 0xff & val; //set SP to the requested value }else if (message.type==V_STATUS) {//Position request (full open / full closed) if (!message.getBool()) { //I Use a inverted blind on the GUI bitSet(New_Cmd,1); //Fire to full close }else{ bitSet(New_Cmd,2); //Fire to full open } } blind1.UpdateRemote_cmd(New_sp,New_Cmd);//Send it to the controller }else if (message.sensor ==CHILD_ID_GAIN_BL1 ){ tmp_Faktor = message.getInt(); if(tmp_Faktor != 0) blind1.Set_Gain_PV(tmp_Faktor); gw.saveState(EPROM_GAIN_BL1,highByte( tmp_Faktor)); gw.saveState(EPROM_GAIN_BL1+1,lowByte( tmp_Faktor)); }else if (message.sensor ==CHILD_ID_SP_BL2 ){ if (message.type == V_DIMMER) { // This is a SP change request int val = message.getInt();//retrieve SP from message bitSet(New_Cmd,0); New_sp = 0xff & val; //set SP to the requested value }else if (message.type==V_STATUS) {//Position request (full open / full closed) if (!message.getBool()) { //I Use a inverted blind on the GUI bitSet(New_Cmd,1); //Fire to full close }else{ bitSet(New_Cmd,2); //Fire to full open } } blind2.UpdateRemote_cmd(New_sp,New_Cmd);//Send it to the controller }else if (message.sensor ==CHILD_ID_GAIN_BL2 ){ tmp_Faktor = message.getInt(); if(tmp_Faktor != 0) blind2.Set_Gain_PV(tmp_Faktor); gw.saveState(EPROM_GAIN_BL2,highByte( tmp_Faktor)); gw.saveState(EPROM_GAIN_BL2+1,lowByte( tmp_Faktor)); } }
Header file ""Rfm69_BlindController.h"
// Only modify this file to include // - function definitions (prototypes) // - include files // - extern variable definitions // In the appropriate section #ifndef _BlindController_H_ #define _BlindController_H_ #include "Arduino.h" //add your includes for the project BlindController here #include "MySensor.h" //end of add your includes here //Do not add code below this line #endif /* _BlindController_H_ */
-
RE: Sensebender with RFM69
Well i don't know wich RFM69 you use but i have here a few moteino's and also toy-ing with them i had similar problem no data exchange possible between the two moteino's. whatever i try no connection was builtup. i even unsolder a rfm69HW on the GW and replaced it.. it communicates??? So conclusion bad RFM69 Throw away.. and test further. After a few days again same problem. Now it was on the breadboard so replacing was easy. Same as before (replace and works).
Then i loaded up the moteino test program in the sensornode and the GW with the non working RFM69 .... Works like a charm??? switch back to Mysensors works again.. I Can't remeber anymore what i did but you have to look at the code n the utility folder the rfm69.cpp file in the initializer. when there is no encryption (NULL) the encryption string is not written.. so ones it's filled in you can't clear it. I suspect that the problem relies there..
regards, Stefan.