Programma domotica controller

Arduino specifieke Software
Berichten: 4
Geregistreerd: 03 Nov 2017, 15:06

Programma domotica controller

Berichtdoor IvdB » 03 Nov 2017, 15:16

Goedemiddag,

Ik ben al een tijdje bezig met een projectje voor mijn Arduino Mega 2560 gebaseerd op een aantal tutorials van de website
https://www.engineerathome.com/

Een korte beschrijving:
- Verlichting aan/uit schakelen door middel van een webinterface
- Temperatuur meten en loggen in een externe database
- Realtime klok voor de actuele tijd (het is de bedoeling om hier straks events aan te hangen)

Echter doordat het programma steeds groter wordt begin ik tegen een aantal problemen aan te lopen.
Ik heb van de verschillende programma zoals hieronder beschreven verschillende schetsen los getest en dan werkt alles perfect.
Zodra ik de codes ga samenvoegen, loop ik echter tegen wat problemen aan.
Als ik void WebServer() alleen aanroep, doet hij het prima, maar zodra ik daar void sensor(void) er bij ga aanroepen dan gaat het al mis.

Waarschijnlijk heeft dit met timing oid te maken.
Heeft iemand voor mij wat tips om het programma beter op te bouwen?


cpp code
/**************************************************************************************************/
/* Domotica Web Interface */
/* */
/* */
/* */
/**************************************************************************************************/

#include <Ethernet.h> // Ethernetshield
#include <SdFat.h> // SD-kaart op ethernetshield
#include <OneWire.h> // Sensor
#include <DS3231.h> // Realtime klok

//======================================= Ethernet/Webserver =======================================
//Instellingen
byte mac[] = {0x54, 0x34, 0x41, 0x30, 0x30, 0x31};
IPAddress ip(192,168,0,177);
IPAddress gateway(192,168,0,1);
IPAddress subnet(255,255,255,0);

//Initialiseren
EthernetServer server(80);
EthernetClient client;
char webserver[] = "192.168.0.104"; // Webserver adres

//Variabelen webserver
SdFat SD; // SD instance voor lib
SdFile myFile; // file variabele voor sd-library
char buffer; // SD read buffer
char page; // nummer van aangeroepen pagina
int command=0; // nummer van aangeroepen commando

//======================================= Variabelen sensoren ======================================
int sensorLicht; // lichtsensor
int sensorTemperatuur; // temperatuursensor
int ledstatus1=0;

//DS18B20
float celsius, fahrenheit;
int celsius1;
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
int interval = 9000; // Interval tussen 2 meetwaarden 9+1=10s

//======================================= Realtime klok ============================================
DS3231 rtc(SDA, SCL);

//======================================= Overige variablen ========================================
boolean Status = false; // huisstatus false = Afwezig, true = Aanwezig
byte Switches[15]; // waardes van de verschillende switches

//Temperatuursensoren instellen
OneWire ds(5); //

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Setup Routine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void setup() {
//Seriele interface
Serial.begin(9600);

//Webserver
Ethernet.begin(mac, ip, gateway, gateway, subnet); // start ethernet shield
server.begin(); // start server

Serial.println("DomoticaController - v1.1");
Serial.print("IP Address : ");
Serial.println(Ethernet.localIP());
Serial.print("Subnet Mask : ");
Serial.println(Ethernet.subnetMask());
Serial.print("Default Gateway IP: ");
Serial.println(Ethernet.gatewayIP());
Serial.print("DNS Server IP : ");
Serial.println(Ethernet.dnsServerIP());
Serial.println("");

delay(1000);
//SD-kaart starten
SD.begin(4, SPI_FULL_SPEED); // om sd-kaart te initialiseren

//Verlichting
Serial.println("Pin configuratie verlichting:");
pinMode(30, OUTPUT);
Serial.println("Pin 30 OUTPUT");
pinMode(31, OUTPUT);
Serial.println("Pin 31 OUTPUT");
pinMode(32, OUTPUT);
Serial.println("Pin 32 OUTPUT");
pinMode(33, OUTPUT);
Serial.println("Pin 33 OUTPUT");
Serial.println("");

//SPI
pinMode(10, OUTPUT); // ethernet shield uitschakelen
digitalWrite(10, HIGH); // zodat SPI bus vrijkomt
// SS = 10; // ethernet / SD
// MOSI = 11; // ethernet / SD
// MISO = 12; // ethernet / SD
// SCK = 13 // ethernet / SD

//Klok starten
rtc.begin();

//Klok instellen
//rtc.setDOW(SATURDAY); // Set Day-of-Week to SUNDAY
//rtc.setTime(15, 10, 0); // Set the time to 12:00:00 (24hr format)
//rtc.setDate(28, 10, 2017); // Set the date to January 1st, 2014


}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Hoofdprogramma ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void loop() {
//realtime();
//sensor();
WebServer();
ledcontrol();
//DataLogging();

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Webserver ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WebServer() {

// sensoren uitlezen
sensorLicht = analogRead(1) / 10.24; // fictief
sensorTemperatuur = analogRead(2) * 5 / 10.24; // fictief

// listen for incoming clients
client = server.available();
boolean currentLineIsFirst = true;
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
if (page == '1') {
// print contents of html-page

client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();

myFile.open("home.php", O_READ);

Read_File_Upto_FS();

// huismodus
if (Status) {
client.print(F("aan"));
Read_File_Upto_FS();
client.print(F("uit"));
}
else {
client.print(F("uit"));
Read_File_Upto_FS();
client.print(F("aan"));
}

// switches
for (int z = 0; z <= 5; z++) {
Read_File_Upto_FS();
if (Switches[z] == 1) {
client.print(F("aan"));
Read_File_Upto_FS();
client.print(F("uit"));
}
else {
client.print(F("uit"));
Read_File_Upto_FS();
client.print(F("aan"));
}
}

// sensoren
Read_File_Upto_FS();
client.print(sensorLicht);

Read_File_Upto_FS();
client.print(sensorTemperatuur);

// blijf Read_File_Upto_FS() gebruiken totdat alle FS-posities in je html-pagina zijn gevuld...

Read_File_Upto_End();

myFile.close();

}
else {
client.println("HTTP/1.1 403 FORBIDDEN");
client.println("Content-Type: text/html");
client.println();
client.print("<h1>403 FORBIDDEN</h1>");
}
page = 0; // reset page variabele
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
currentLineIsFirst = false;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
if (currentLineIsFirst && c == '?') {
// found ? so read pagenumber
page = client.read();
}
if (currentLineIsFirst && c == '=') {
// found = so read commandnumber
command = client.read() - 48; // convert char to int!!! 0=0 1=1 2=2 a=49 b=50 c=51
command = (10 * command) + (client.read() - 48); // convert char to int!!! 0=0 1=1 2=2 a=49 b=50 c=51
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();


}

}

void Read_File_Upto_FS() {
while ((buffer = myFile.read()) != 28) {
client.print((char)buffer);
}
}

void Read_File_Upto_End() {
while ((buffer = myFile.read()) >= 0) {
client.print((char)buffer);
}
}

void Skip_File_Upto_FS() {
while ((buffer = myFile.read()) != 28) {
// nothing
}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Verlichting ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ledcontrol(){
if (command==10) {
digitalWrite(30, HIGH);
Serial.println("commando:");
Serial.println(command);
}

if (command==11) {
digitalWrite(30, LOW);
Serial.println("commando:");
Serial.println(command);
}

if (command==20) {
digitalWrite(31, HIGH);
Serial.println("commando:");
Serial.println(command);
}

if (command==21) {
digitalWrite(31, LOW);
Serial.println("commando:");
Serial.println(command);
}

if (command==30) {
digitalWrite(32, HIGH);
Serial.println("commando:");
Serial.println(command);
}

if (command==31) {
digitalWrite(32, LOW);
Serial.println("commando:");
Serial.println(command);
}

if (command==40) {
digitalWrite(33, HIGH);
Serial.println("commando:");
Serial.println(command);
}

if (command==41) {
digitalWrite(33, LOW);
Serial.println("commando:");
Serial.println(command);
}

if (command==93) {
digitalWrite(30, HIGH);
digitalWrite(31, HIGH);
digitalWrite(32, HIGH);
digitalWrite(33, HIGH);
Serial.println("commando:");
Serial.println(command);
}

if (command==94) {
digitalWrite(30, LOW);
digitalWrite(31, LOW);
digitalWrite(32, LOW);
digitalWrite(33, LOW);
Serial.println("commando:");
Serial.println(command);
}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Temperatuur ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void sensor(void) {
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(250);
return;
}

Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}

if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();

// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.println(" Chip = DS18S20"); // or old DS1820
type_s = 1;
break;
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}

ds.reset();
ds.select(addr);
ds.write(0x44); // start conversion, use ds.write(0x44,1) with parasite power on at the end

delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.

present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad

Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();

// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
Serial.println("");
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Real Time Klok ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void realtime(){
Serial.print("Tijd en Datum : ");
// Send Day-of-Week
Serial.print(rtc.getDOWStr());
Serial.print(" ");

// Send date
Serial.print(rtc.getDateStr());
Serial.print(" -- ");

// Send time
Serial.println(rtc.getTimeStr());

// Wait one second before repeating :)
delay (1000);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Datalogging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void DataLogging() {
// if you get a connection, report back via serial:
if (client.connect(webserver, 80)) {
Serial.println("-> Connected");

// Make a HTTP request:
client.print( "GET /logger/add_data.php?");
client.print("serial=");
client.print("");
client.print("&");
client.print("temperature=");
client.print(celsius);
client.println( " HTTP/1.1");
client.println( "Host: 192.168.0.4" );
client.println( "Content-Type: application/x-www-form-urlencoded" );
client.println( "Connection: close" );
client.println();
client.println();
client.stop();
}
else {
// you didn't get a connection to the server:
Serial.println("--> connection failed/n");
}

delay(interval);
}

Advertisement

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Programma domotica controller

Berichtdoor nicoverduin » 03 Nov 2017, 16:07

Hoe raar het ook klinkt.... Dit is een vrij exacte wetenschap. Dus als iemand zegt "het gaat mis" heb ik geen idee wat er dan mis gaat. Komt er rook uit?.... Vliegt de meterkast in brand? Dus graag wat specifieker....
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 4
Geregistreerd: 03 Nov 2017, 15:06

Re: Programma domotica controller

Berichtdoor IvdB » 03 Nov 2017, 16:55

Sorry, ik zal iets concreter zijn.
Het lijkt er sterk op dat delen van de code niet goed worden uitgevoerd.
Als ik namelijk het stukje code van de webserver alleen aanroep in de loop dan wordt de webinterface goed weergegeven.
Zodra ik daar een ander stukje code bij aanroep bijvoorbeeld de code van de sensor dan wordt de webinterface niet meer weergegeven.
Vandaar dat ik denk ik dat er iets mis gaat met timing of iets dergelijks.

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Programma domotica controller

Berichtdoor nicoverduin » 03 Nov 2017, 19:57

Mijn eerste reactie zou zijn sloop al die delays eruit en ga met timers werken in de loop
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 4067
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Programma domotica controller

Berichtdoor shooter » 04 Nov 2017, 10:40

ik zag ineens SDA en SCL staan, maar geen waardes,
paul deelen
shooter@home.nl

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Programma domotica controller

Berichtdoor Koepel » 04 Nov 2017, 15:09

Dat mag. Voor ieder Arduino board is de "SDA" en "SCL" als pinnummer gedefinieerd.
Wat die in de sketch doen, dat weet ik niet. Zo iets wordt gedaan bij een softwarematige I2C library.
De "SDA" en "SCL" maken het ook mogelijk met algemene code om de pullup resistors uit te zetten door na Wire.begin() de SDA en SCL een setMode met INPUT te doen (tegenwoordig verdwijnt de pullup resistor als "INPUT" wordt gedaan).

Berichten: 4
Geregistreerd: 03 Nov 2017, 15:06

Re: Programma domotica controller

Berichtdoor IvdB » 06 Nov 2017, 22:02

Bedankt voor jullie reacties.
Ik heb de code inmiddels helemaal werkend gekregen.
Heb wat delays verwijderd uit de code en vervangen door timers.
Het probleem zit voornamelijk in het ophalen van de sensor data.
Dit stukje code wordt nu eens in de x-tijd uitgevoerd en daarmee is het probleem opgelost.
Nogmaals bedankt voor jullie reacties.

Berichten: 2
Geregistreerd: 01 Mei 2018, 16:45

Re: Programma domotica controller

Berichtdoor wayward » 01 Mei 2018, 16:47

IvdB schreef:Bedankt voor jullie reacties.
Ik heb de code inmiddels helemaal werkend gekregen.
Heb wat delays verwijderd uit de code en vervangen door timers.
Het probleem zit voornamelijk in het ophalen van de sensor data.
Dit stukje code wordt nu eens in de x-tijd uitgevoerd en daarmee is het probleem opgelost.
Nogmaals bedankt voor jullie reacties.


Heey... Deze code komt mij bekend voor, ik probeer er een 16 Relay boardje tussen te proppen, maar als ik hem uitbreid word de web interface onwerkbaar. Ik zou graag jou code zien!

Berichten: 2
Geregistreerd: 01 Mei 2018, 16:45

Re: Programma domotica controller

Berichtdoor wayward » 01 Mei 2018, 17:04

wayward schreef:
IvdB schreef:Bedankt voor jullie reacties.
Ik heb de code inmiddels helemaal werkend gekregen.
Heb wat delays verwijderd uit de code en vervangen door timers.
Het probleem zit voornamelijk in het ophalen van de sensor data.
Dit stukje code wordt nu eens in de x-tijd uitgevoerd en daarmee is het probleem opgelost.
Nogmaals bedankt voor jullie reacties.


Heey... Deze code komt mij bekend voor, ik probeer er een 16 Relay boardje tussen te proppen, maar als ik hem uitbreid word de web interface onwerkbaar. Ik zou graag jou code zien!


Ik denk dat ik hem al heb, als je een getal invoert in: Page_Home.ino

Dus voor code:
Code: Alles selecteren
  // switches relay board
  for (int z = 20; z <= 21; z++) {
    Read_File_Upto_FS();
    if (Switches[z] == 1) {
      client.print(F("aan"));
      Read_File_Upto_FS();
      client.print(F("uit"));
    }
    else {
      client.print(F("uit"));
      Read_File_Upto_FS();
      client.print(F("aan"));
    }
  }


Heb je in home.htm ook een blok nodig die ertegenover staat:

Code: Alles selecteren
         <li>
            <span>Versterker aan</span>
            <div class="amplifier"></div>
            <p>
               <a href="?1=20" class="">Aan</a>
               <a href="?1=20" class="">Uit</a>
            </p>
         </li>


Anders loopt de web interface dus vast.

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: goodmen999, piniqex en 7 gasten