• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
MySensors + Mega 2560 + DS18B20 + Relay
#1
Pracą kotłowni zarządza Arduino Mega 2560. Próbuję zintegrować to z Home Assistantem przy pomocy MySensors. Chciałbym mieć podgląd temperatur z czujników podłączonych do Arduino, oraz sterować przekaźnikami, które chciałbym dołożyć. Korzystając z instrukcji na stronie Ethernet Gateway połączyłem systemy przy pomocy karty sieciowej W5100. Zmodyfikowałem sketch Temperature Sensor i udało mi się odczytac parametry czujników w HA. Po zaadaptowaniu sketchu Example with button uzyskałem możliwość sterowania z poziomu HA przekaźnikiem podpiętym do Arduino. Oba sketche indywidualnie działają bez problemów. Gdy każdy z nich indywidualnie zintegruje ze sketchem sterującym kotłownią również wszystko działa. Nie mogę sobie jednak poradzić z połączeniem odczytu temperatur i sterowania przekaźnikiem w jednym programie. Próbowałem różnych modyfikacji, jednak ogarniam to na poziomie kopiuj-wklej i albo program się nie kompiluje, albo czujniki i przekaźniki nie są widoczne w HA. 

Sketch wygląda tak:
Kod:
#define MY_DEBUG // Enable debug prints to serial monitor
#define MY_GATEWAY_W5100 // Enable gateway ethernet module type
#define MY_IP_ADDRESS 192,168,68,130 // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
#define MY_PORT 5003 // The port to keep open on node server mode / or port to contact in client mode
#define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
#define MY_INCLUSION_MODE_FEATURE // Enable inclusion mode
#define MY_INCLUSION_MODE_DURATION 60 // Set inclusion mode duration (in seconds)
#define MY_DEFAULT_LED_BLINK_PERIOD 300 // Set blinking period
#define MY_REPEATER_FEATURE

#if defined(MY_USE_UDP)
#include <EthernetUdp.h>
#endif
#include <Ethernet.h>
#include <MySensors.h>
#include <Bounce2.h>
#include <DallasTemperature.h>
#include <OneWire.h>

#define RELAY_PIN  4  // Arduino Digital I/O pin number for relay
#define BUTTON_PIN  3  // Arduino Digital I/O pin number for button
#define CHILD_ID 1   // Id of the sensor child
#define RELAY_ON 0
#define RELAY_OFF 1
#define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
#define ONE_WIRE_BUS A5 // Pin where dallase sensor is connected
#define MAX_ATTACHED_DS18B20 16
#define LED1pin 13 // LED1 do pinu 13

Bounce debouncer = Bounce();
int oldValue=0;
bool state;

MyMessage msg(CHILD_ID,V_LIGHT);
MyMessage msg(0,V_TEMP); // Initialize temperature message

unsigned long SLEEP_TIME = 3000; // Sleep time between reads (in milliseconds)

OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.

DeviceAddress Koc = { 0x28, 0x9E, 0xB1, 0xB5, 0xD, 0x0, 0x0, 0x3E };
DeviceAddress Kocp = { 0x28, 0xFF, 0x25, 0x96, 0x28, 0x20, 0x1B, 0x47 };
DeviceAddress Buf1 = { 0x28, 0xFF, 0xF7, 0x95, 0x28, 0x20, 0x1B, 0x12 };

float lastTemperature[MAX_ATTACHED_DS18B20];
int numSensors=0;
bool receivedConfig = false;
bool metric = true;


void before()

{
  sensors.begin(); // Startup up the OneWire library
}

void setup() 

  // Setup the button
  pinMode(BUTTON_PIN,INPUT);
  // Activate internal pull-up
  digitalWrite(BUTTON_PIN,HIGH);
 
  // After setting up the button, setup debouncer
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5);

  // Make sure relays are off when starting up
  digitalWrite(RELAY_PIN, RELAY_OFF);
  // Then set relay pins in output mode
  pinMode(RELAY_PIN, OUTPUT);  
     
  // Set relay to last known state (using eeprom storage)
  state = loadState(CHILD_ID);
  digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
}

void presentation()  {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("Relay & Button", "1.0");
  numSensors = sensors.getDeviceCount(); // Fetch the number of attached temperature sensors
  for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) // Present all sensors to controller
  {  
     present(i, S_TEMP);
  }

  // Register all sensors to gw (they will be created as child devices)
  present(CHILD_ID, S_LIGHT);
}

/*
*  Example on how to asynchronously check for new messages from gw
*/
void loop()
{
  sensors.requestTemperatures(); // Fetch temperatures from Dallas sensors
  debouncer.update();
  // Get the update value
  int value = debouncer.read();
  if (value != oldValue && value==0) {
      send(msg.set(state?false:true), true); // Send new state and request ack back
  }
  oldValue = value;
    int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());  // query conversion time and sleep until conversion completed
  sleep(conversionTime); // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
  for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) // Read temperatures and send them to controller
  {
    float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; // Fetch and round temperature to one decimal
    // Only send data if temperature has changed and no error
    #if COMPARE_TEMP == 1
    if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00)
    {
    #else
    if (temperature != -127.00 && temperature != 85.00)
    {
    #endif
      send(msg.setSensor(i).set(temperature,1)); // Send in the new temperature
      lastTemperature[i]=temperature;  // Save new temperatures for next compare
    }
  }
 
  sleep(SLEEP_TIME);
  }


void receive(const MyMessage &message) {
  // We only expect one type of message from controller. But we better check anyway.
  if (message.isAck()) {
     Serial.println("This is an ack from gateway");
  }

  if (message.type == V_LIGHT) {
     // Change relay state
     state = message.getBool();
     digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
     // Store state in eeprom
     saveState(CHILD_ID, state);
   
     // Write some debug info
     Serial.print("Incoming change for sensor:");
     Serial.print(message.sensor);
     Serial.print(", New status: ");
     Serial.println(message.getBool());
   }
}


Przy próbie kompilacji pojawiają się takie błędy:


Kod:
Arduino:1.8.19 (Windows 10), Płytka:"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"




MySensors_przekaznik_czujnik:36:14: error: redefinition of 'MyMessage msg'

C:\Users\Paweł\Desktop\MySensors\MySensors_przekaznik_czujnik\MySensors_przekaznik_czujnik.ino:35:11: note: 'MyMessage msg' previously declared here

exit status 1

redefinition of 'MyMessage msg'


Rozumiem, ze parametr "MyMessage msg" może być użyty tylko raz, jednak sketch dla czujników temperatury ma inne wartości i dla przekaźników inne. Jak to poprawnie połączyć?
 
Odpowiedź
#2
MyMessage msg1(CHILD_ID,V_LIGHT);
MyMessage msg2(0,V_TEMP); // Initialize temperature message

a potem w miejscu ich użycia:
send(msg1.set(state?false:true), true); // Send new state and request ack back
send(msg2.setSensor(i).set(temperature,1)); // Send in the new temperature

zastanów się nad używaniem sleep(SLEEP_TIME) - czy w ten sposób nie zatrzymujesz przypadkiem wykonywania pętli? Jeżeli tak to nie będzie działać przycisk i temperatura jednocześnie

Prośba do bardziej doświadczonych kolegów o weryfikację, bo z MySensors nigdy nie pracowałem.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości