probleem met een output hoog gedurende een bepaalde tijd

Arduino specifieke Software
Berichten: 97
Geregistreerd: 05 Nov 2014, 22:04

probleem met een output hoog gedurende een bepaalde tijd

Berichtdoor MarcelK » 10 Sep 2015, 12:16

En ik heb weer eens ruzie met millis(), wil er schijnbaar gewoon niet in bij mij ;-)

Wat is het geval: ik heb een zonwering op een voliere buiten welke afhankelijk van de lichtsterkte en temperatuur open of dicht moet gaan.
De motor welke het scherm opent of sluit draait maar 2 rpm, en heeft dan 155 seconden nodig om het scherm volledig open of dicht te sturen.
Eindschakelaars met reedcontact of hallsensor is mechanisch gezien niet uitvoerbaar dus heb ik gekozen voor de looptijd van de motor.
Delay stopt de rest van de software dus is geen optie aangezien er nog meer moet gebeuren (verzenden van temperaturen etc.)

Hieronder is de uitgeklede sketch, alles wat niet terzake doet voor de motoraansturing is weggelaten.

Kan iemand me op weg helpen svp ?

Code: Alles selecteren
#include <DallasTemperature.h>
#include <EEPROM.h>

long ScanInterval = 10*1000; // Poll om de 10 seconden
long ScanCounter = 0;

long OpenInterval = 15*1000; // moet 155 seconden zijn
long OpenCounter = 0;

long DichtInterval = 10*1000; // moet 155 seconden zijn
long DichtCounter = 0;

// DS18B20 is plugged into Arduino D4
#define ONE_WIRE_BUS 4
#define TEMPERATURE_PRECISION 12
// LDR op pin A0
#define LDRPin A0

//Pinbezetting naar motorshield L293D
const int OpenPin=5;
const int DichtPin=6;
const int SnelheidPin=3;

// variabelen tbv zonwering
int OpenCMD=0;
int SluitCMD=0;
int OpenTeller = 0;
int DichtTeller = 0;
const int VertragingOpen = 2; // mag pas open gaan na 30 minuten LDR<limit en temp<limit
const int VertragingDicht = 2; // mag pas dicht gaan na 5 minuten LDR>limit en Temp>limit

/* limiet schakelpunten */
const float TempLimit1=22.0;
const int LichtLimit=900;

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
DeviceAddress outsideThermometer1;
DeviceAddress outsideThermometer2;
float temp1C;
float temp2C;
byte nodestatus=0;
int lichtsterkte;


// Prototypes
void getTemperature(DeviceAddress);   // getTemperature
void sendPayload();              // check if time to send payload
void MotorOpen();                       // Motor openen = zonwering gaat open
void MotorDicht();                      // Motor Sluiten = zonwering gaat dicht
void MotorStop();                       // Motor stoppen

void setup(void){
  // Start up the library
  sensors.begin();
  //sensors.setResolution(insideThermometer,TEMPERATURE_PRECISION);
  sensors.getAddress(outsideThermometer1, 1);
  sensors.setResolution(outsideThermometer1,TEMPERATURE_PRECISION);
  sensors.getAddress(outsideThermometer2, 2);
  sensors.setResolution(outsideThermometer2,TEMPERATURE_PRECISION);
  MotorStop(); // zet de motor uit
  Serial.begin(9600);
  pinMode(DichtPin, OUTPUT);
  pinMode(SnelheidPin, OUTPUT);
  int value = EEPROM.read(0);
  Serial.print("Opstartwaarde: ");
  Serial.println(value);
  if (value==0){
    Serial.println("Scherm is OPEN");
    OpenCMD=1;
    SluitCMD=0;
  }
  if (value==1){
    Serial.println("Scherm is DICHT");
    OpenCMD=0;
    SluitCMD=1;
  }
  Serial.println("#####################");
}


void loop(void){
  // Pump the network regularly
  if(millis() - ScanCounter > ScanInterval)
  {
    ScanCounter=millis();
    //network.update();
    getTemperature();
    getLichtsterkte();
    //sendPayload();
    // als de temperatuur en lichtsterkte te hoog worden dan na wachttijd
    // van 5 minuten de zonwering sluiten
    if ((temp1C > TempLimit1) && (lichtsterkte > LichtLimit)) { // als temperatuur>23 en lichtsterkte>900
      if (SluitCMD==0){
        DichtTeller++;
      }
    }

    if (DichtTeller >= VertragingDicht){
      SluitCMD=1;  // zonwering sluiten
      OpenCMD=0;
    }

    // zonwering pas openen als temperatuur en lichtsterkte gedurende 1 uur onder de drempel liggen
    if ((temp1C < TempLimit1) && (lichtsterkte < LichtLimit)) { // als temperatuur<23 en lichtsterkte<800
      if (SluitCMD==1){
        OpenTeller++;
      }
    }
    if (OpenTeller >= VertragingOpen){
      OpenCMD=1; // zonwering openen
      SluitCMD=0;
    }

    if (OpenCMD == 1){
      OpenCounter=millis();
      MotorOpen();
    }

    if (SluitCMD == 1){
      DichtCounter=millis();
      MotorDicht();
    }
  }

}


//////////////////////////////////////////////////////////////////
// getTemperature
//////////////////////////////////////////////////////////////////
void getTemperature(){
  sensors.requestTemperatures();
  temp1C = sensors.getTempCByIndex(0);
  temp2C = sensors.getTempCByIndex(1);
  //temp3C = sensors.getTempCByIndex(2);
  Serial.println("Temperaturen ophalen..");
  Serial.print("Sensor 1: ");
  Serial.println(temp1C);
  Serial.print("Sensor 2: ");
  Serial.println(temp2C);
  Serial.print("Zonwering: ");
  Serial.println(nodestatus);
  Serial.print("OpenCMD: ");
  Serial.println(OpenCMD);
  Serial.print("SluitCMD: ");
  Serial.println(SluitCMD);
  Serial.print("Openteller: ");
  Serial.println(OpenTeller);
  Serial.print("DichtTeller: ");
  Serial.println(DichtTeller);
}

//////////////////////////////////////////////////////
// Haal lichtsterkte op
//////////////////////////////////////////////////////
void getLichtsterkte(){
  int waarde = analogRead(LDRPin);
  //lichtsterkte = map(waarde,0,1023,0,100);  //12-6 mapping weg
  lichtsterkte=waarde;
  Serial.print("Lichtsterkte: ");
  Serial.println(lichtsterkte);
}

void MotorOpen(){ // zonwering gaat open
  int value = EEPROM.read(0);
  Serial.print("MotorOpen: Epromvalue=");
  Serial.println(value);
  Serial.println("----------------------");
  if (value!=0) { // als zonwering al open is niets doen
    Serial.println("Zonwering gaat open");
    Serial.println("----------------------");
    if(millis() - OpenCounter > OpenInterval)
    {
      digitalWrite(OpenPin,HIGH);
      digitalWrite(DichtPin,LOW);
      analogWrite(SnelheidPin,255);
      Serial.print("OpenCounter:");
      Serial.println(OpenCounter);
      OpenCounter=millis();
    }
    MotorStop();
    EEPROM.write(0, 0);
    DichtTeller=0;
    OpenTeller=0;
  }
  nodestatus=0;
}

void MotorDicht(){ // zonwering gaat dicht
  int value = EEPROM.read(0);
  Serial.print("MotorDicht: Epromvalue=");
  Serial.println(value);
  Serial.println("----------------------");
  if (value!=1) { // als zonwering al dicht is niets doen
    Serial.println("Zonwering gaat dicht");
    Serial.println("----------------------");
    if(millis() - DichtCounter > DichtInterval)
    {     
      digitalWrite(OpenPin,LOW);
      digitalWrite(DichtPin,HIGH);
      analogWrite(SnelheidPin,255);
      Serial.print("DichtCounter:");
      Serial.println(DichtCounter);
      DichtCounter=millis();
    }
    MotorStop();
    EEPROM.write(0, 1);
    DichtTeller=0;
    OpenTeller=0;
  }
  nodestatus=5;
}

void MotorStop(){
  digitalWrite(OpenPin,LOW);
  digitalWrite(DichtPin,LOW);
  analogWrite(SnelheidPin,0);
  Serial.println("Motor gestopt");
  Serial.println("----------------------");
}


Advertisement

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

Re: probleem met een output hoog gedurende een bepaalde tijd

Berichtdoor nicoverduin » 10 Sep 2015, 13:00

timers moeten unsigned long zijn en niet long. unsigned betekent dat hij nooit negatief kan worden. Bij jouw wel en dat is de goden verzoeken......
15 * 1000 = 15 seconden en geen 155 seconden.....
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 97
Geregistreerd: 05 Nov 2014, 22:04

Re: probleem met een output hoog gedurende een bepaalde tijd

Berichtdoor MarcelK » 10 Sep 2015, 14:04

nicoverduin schreef:timers moeten unsigned long zijn en niet long. unsigned betekent dat hij nooit negatief kan worden. Bij jouw wel en dat is de goden verzoeken......
15 * 1000 = 15 seconden en geen 155 seconden.....


die unsigned had ik overheen gekeken, dank je wel Nico.

die 15 seconden had ik er gezet tbv testen, achter de // de tijd die het moet zijn in de definitieve sketchb ;)

Berichten: 97
Geregistreerd: 05 Nov 2014, 22:04

Re: probleem met een output hoog gedurende een bepaalde tijd

Berichtdoor MarcelK » 10 Sep 2015, 15:11

MarcelK schreef:
nicoverduin schreef:timers moeten unsigned long zijn en niet long. unsigned betekent dat hij nooit negatief kan worden. Bij jouw wel en dat is de goden verzoeken......
15 * 1000 = 15 seconden en geen 155 seconden.....


die unsigned had ik overheen gekeken, dank je wel Nico.

die 15 seconden had ik er gezet tbv testen, achter de // de tijd die het moet zijn in de definitieve sketchb ;)

Was vergeten om onderstaand erbij te zetten..

Het probleem zit echter in de functies MotorOpen en MotorDicht, die moeten een bepaalde tijd (15 of 155 seconden) de motor laten lopen en dat gebeurt dus niet.
Ik zie ongetwijfeld iets over het hoofd.

Berichten: 97
Geregistreerd: 05 Nov 2014, 22:04

Re: probleem met een output hoog gedurende een bepaalde tijd

Berichtdoor MarcelK » 12 Sep 2015, 21:05

Mochten er mensen zijn die nog tips hebben: niet meer nodig, probleem is opgelost.

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

Re: probleem met een output hoog gedurende een bepaalde tijd

Berichtdoor shooter » 14 Sep 2015, 22:07

en waar had je over heen gekeken.
wel een best lang programma lijkt mij voor simpel ding
paul deelen
shooter@home.nl

Berichten: 97
Geregistreerd: 05 Nov 2014, 22:04

Re: probleem met een output hoog gedurende een bepaalde tijd

Berichtdoor MarcelK » 15 Sep 2015, 21:44

De Loop draait iedere 10 seconden zijn rondje en kijkt naar de gemeten waardes van temperatuur 1 en een ldr.
als beiden boven een limiet komen dan moet er een motortje gaan lopen gedurende 155 seconden.
En daar zat de kneep, bij het volgende rondje was de voorwaarde er nog en gaf hij weer het commando naar het openstuurgedeelte en bleef hij oneindig in die lus en had geen tijd meer om iets anders te doen.

echter binnen de loop wordt er ook nog meetgegevens verstuurd dmv een nrf24l01 en daar kwam hij dus ook niet meer aan toe.

Heb het opgelost dmv een teller die indien de limiet bereikt is de motoraansturing inschakelt en dit zo houdt tot de tellerstand bereikt is.
iedere 10 seconden wordt de teller opgehoogd door de loop.
Looptijd is nu 150 seconden ipv 155 seconden maar dat is voldoende.

Sketch is misschien wat lang, maar de enigste opbouwende kritiek die ik tot nu toe gekregen heb is een dat er voor de intervaltimer een unsigned long ipv een long gebruikt moet worden.
Had ik overheen gekeken, maar was niet de oorzaak van het niet werken, de sketch zonder motoraansturing draaide al een half jaar 24 uur per dag zonder problemen.
Heb echter wel de unsigned long erin gezet, Nico had helemaal gelijk, kan problemen opleveren.

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: exujuvrexpe en 83 gasten