Man kan använda vanlig 433 mhz sändare som de har på kjelles.
http://www.kjell.com/sortiment/el/elekt ... dul-p88901
Jag gjorde ett fulhack med en nexxa strömplugg + 1wire tempsensor för att styra sousvide vattenbad med PID.
Kräven en hel del libs för att fungera och nej jag suger på kod/kommentarer.
Mest cut n paste från andra exempel.
Kod: Markera allt
#include <math.h>
#include "HomeEasy.h"
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <serLCD.h>
#include <SoftwareSerial.h>
#include <PID_v1.h>
HomeEasy homeEasy;
// Set pin to the LCD's rxPin
int lcdpin = 6;
// Buttons are connected (top to bottom) as follows:
#define BUTTON1_PIN 10
#define BUTTON2_PIN 11
// Data wire is plugged into port 5 on the Arduino
#define ONE_WIRE_BUS 5
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
serLCD lcd(lcdpin);
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
boolean relayState = LOW;
boolean changeRelay;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, 10, 50, 10, DIRECT);
unsigned long serialTime; //this will help us know when to talk with processing
int WindowSize = 5000;
unsigned long windowStartTime;
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
void setup()
{
pinMode(BUTTON1_PIN, INPUT);
pinMode(BUTTON2_PIN, INPUT);
lcd.clear();
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
homeEasy = HomeEasy();
homeEasy.registerSimpleProtocolHandler(printSimpleResult);
homeEasy.registerAdvancedProtocolHandler(printAdvancedResult);
homeEasy.init();
unsigned long sender = 7969226;
unsigned int recipient = 0;
bool command = false;
bool group = false;
homeEasy.sendAdvancedProtocolMessage(sender, recipient, command, group);
lcd.clear();
//Start 1wire lib
sensors.begin();
Setpoint = 62.00;
relayState = LOW;
Input = sensors.getTempCByIndex(0);
windowStartTime = millis();
//tell the PID to range between 0 and the full window size
myPID.SetOutputLimits(0, WindowSize);
//turn the PID on
myPID.SetMode(AUTOMATIC);
}
void setCursor(int r, int c) { // 1-4, 1-20
int x = 0x80;
// Start with the row
switch (r) {
case 1: x+= 0; break;
case 2: x+= 64; break;
case 3: x+= 20; break;
case 4: x+= 84; break;
default: x+=0;
}
// And now add the column
if (c > 0 && c < 21) {
x+= c-1;
}
lcd.write(0xfe); delay(5);
lcd.write(x); delay(5);
delay (5);
}
void loop()
{
while (digitalRead(BUTTON1_PIN) == HIGH) {
// incriment
Setpoint+=0.1;
setCursor(4,1);
lcd.print("SP:");
lcd.print(Setpoint);
delay(100);
}
while (digitalRead(BUTTON2_PIN) == HIGH) {
// decriment
Setpoint-=0.1;
setCursor(4,1);
lcd.print("SP:");
lcd.print(Setpoint);
delay(100);
}
sensors.requestTemperatures(); // Send the command to get temperatures
// Serial.print("Temperature for the device 1 (index 0) is: ");
// Serial.println(sensors.getTempCByIndex(0));
setCursor(1,1);
lcd.print("Water:");
lcd.print(sensors.getTempCByIndex(0));
lcd.print((char)223);
lcd.print("C");
setCursor(2,1);
lcd.print("Onboard:");
lcd.print(sensors.getTempCByIndex(1), (byte) 2);
lcd.print((char)223);
lcd.print("C");
setCursor(4,1);
lcd.print("SP:");
lcd.print(Setpoint);
Input = sensors.getTempCByIndex(0);
myPID.Compute();
/************************************************
* turn the output pin on/off based on pid output
************************************************/
if(millis() - windowStartTime>WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
setCursor(4,10);
lcd.print(Output);
unsigned long now = millis();
if(now - windowStartTime>WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if(Output > now - windowStartTime) {
if (relayState == LOW) {
relayState=HIGH;
unsigned long sender = 7969226;
unsigned int recipient = 0;
bool command = true;
bool group = false;
homeEasy.sendAdvancedProtocolMessage(sender, recipient, command, group);
setCursor(3,1);
lcd.print("ON ");
}
}
else {
if (relayState == HIGH) {
relayState=LOW;
unsigned long sender = 7969226;
unsigned int recipient = 0;
bool command = false;
bool group = false;
homeEasy.sendAdvancedProtocolMessage(sender, recipient, command, group);
setCursor(3,1);
lcd.print("OFF");
}
}
//send-receive with processing if it's time
if(millis()>serialTime)
{
SerialReceive();
SerialSend();
serialTime+=500;
}
}
/********************************************
* Serial Communication functions / helpers
********************************************/
union { // This Data structure lets
byte asBytes[24]; // us take the byte array
float asFloat[6]; // sent from processing and
} // easily convert it to a
foo; // float array
// getting float values from processing into the arduino
// was no small task. the way this program does it is
// as follows:
// * a float takes up 4 bytes. in processing, convert
// the array of floats we want to send, into an array
// of bytes.
// * send the bytes to the arduino
// * use a data structure known as a union to convert
// the array of bytes back into an array of floats
// the bytes coming from the arduino follow the following
// format:
// 0: 0=Manual, 1=Auto, else = ? error ?
// 1: 0=Direct, 1=Reverse, else = ? error ?
// 2-5: float setpoint
// 6-9: float input
// 10-13: float output
// 14-17: float P_Param
// 18-21: float I_Param
// 22-245: float D_Param
void SerialReceive()
{
// read the bytes sent from Processing
int index=0;
byte Auto_Man = -1;
byte Direct_Reverse = -1;
while(Serial.available()&&index<26)
{
if(index==0) Auto_Man = Serial.read();
else if(index==1) Direct_Reverse = Serial.read();
else foo.asBytes[index-2] = Serial.read();
index++;
}
// if the information we got was in the correct format,
// read it into the system
if(index==26 && (Auto_Man==0 || Auto_Man==1)&& (Direct_Reverse==0 || Direct_Reverse==1))
{
Setpoint=double(foo.asFloat[0]);
//Input=double(foo.asFloat[1]); // * the user has the ability to send the
// value of "Input" in most cases (as
// in this one) this is not needed.
if(Auto_Man==0) // * only change the output if we are in
{ // manual mode. otherwise we'll get an
Output=double(foo.asFloat[2]); // output blip, then the controller will
} // overwrite.
double p, i, d; // * read in and set the controller tunings
p = double(foo.asFloat[3]); //
i = double(foo.asFloat[4]); //
d = double(foo.asFloat[5]); //
myPID.SetTunings(p, i, d); //
if(Auto_Man==0) myPID.SetMode(MANUAL);// * set the controller mode
else myPID.SetMode(AUTOMATIC); //
if(Direct_Reverse==0) myPID.SetControllerDirection(DIRECT);// * set the controller Direction
else myPID.SetControllerDirection(REVERSE); //
}
Serial.flush(); // * clear any random data from the serial buffer
}
// unlike our tiny microprocessor, the processing ap
// has no problem converting strings into floats, so
// we can just send strings. much easier than getting
// floats from processing to here no?
void SerialSend()
{
Serial.print("PID ");
Serial.print(Setpoint);
Serial.print(" ");
Serial.print(Input);
Serial.print(" ");
Serial.print(Output);
Serial.print(" ");
Serial.print(myPID.GetKp());
Serial.print(" ");
Serial.print(myPID.GetKi());
Serial.print(" ");
Serial.print(myPID.GetKd());
Serial.print(" ");
if(myPID.GetMode()==AUTOMATIC) Serial.print("Automatic");
else Serial.print("Manual");
Serial.print(" ");
if(myPID.GetDirection()==DIRECT) Serial.println("Direct");
else Serial.println("Reverse");
}
/**
* Print the details of the advanced protocol message.
*/
void printAdvancedResult(unsigned long sender, unsigned int recipient, bool on, bool group)
{
Serial.println("advanced protocol message");
Serial.print("sender ");
Serial.println(sender);
Serial.print("recipient ");
Serial.println(recipient);
Serial.print("on ");
Serial.println(on);
Serial.print("group ");
Serial.println(group);
Serial.println();
}
/**
* Print the details of the simple protocol message.
*/
void printSimpleResult(unsigned int sender, unsigned int recipient, bool on)
{
Serial.println("simple protocol message");
Serial.print("sender ");
Serial.println(sender);
Serial.print("recipient ");
Serial.println(recipient);
Serial.print("on ");
Serial.println(on);
Serial.println();
}