Hulp nodig voor stageopdracht

Hallo,

Ik ben sinds kort begonnen met Arduino. Voor een stageopdracht moet ik een polariteitsmeter maken die ziet of de magneten goed zijn gelijmd. (Noordpool - zuidpool - noordpool - zuidpool enz) Dit wordt gedaan door middel van Hall-sensoren om en om te plaatsen tegenover de magneten. In mijn schakeling zijn ook twee 12V DC elektromagneten aanwezig om een klep dicht te houden tijdens de meting. Verder wordt er weergegeven op een LCD wat de operator moet doen. Er zullen ook LED’s en drukknoppen aanwezig zijn.

Omdat ik niet genoeg I/O’s heb maak ik gebruik van een I/O expander (PCF8574AN) Hier zal ik 6 inputs van gebruiken op de expander. Er zullen 3 detectiesensoren (Hall-sensor) aanwezig zijn die ieder een input op de expander krijgt. Verder 3 inputs voor de Hall-sensoren die parallel aan elkaar staan en die de daadwerkelijke meting uit gaan voeren.

Ik heb alle schakelingen individueel getest met de Arduino. LCD, elektromagneten, drukknoppen, LED’s, Hall-sensoren en dit werkt allemaal goed.Nu moet ik alles samenvoegen in één programma alleen hier loop ik vast. Het LCD geeft al text weer terwijl dit eigenlijk nog niet mag. Ik kom er niet meer uit.

Ik zal een stappenplan sturen van wat er moet gebeuren en de schema’s.

Hieronder mijn code tot zover:

// de library codes
#include <LiquidCrystal.h> 
#include <Wire.h>
#define PCF8574AN 0x38          //Definieer de I/O expander 

// initialiseren het LCD met de nummers van de interface pinnen
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int ledred = 13;          //LED rood op pin 13 
const int ledyellow = 9;        //LED geel op pin 9
const int ledgreen = 8;         //LED groen op pin 8 
const int ledblue = 6;          //LED blauw op pin 6
const int lidswitch = 14;       //Drukknop op aan de achterkant op pin A0 (14)
const int startswitch = 15;     //Drukknop aan de voorkant 
const int resetswitch = 16;     //Reset knop 
const int magnetpin = 10;       //Elektromagneten 
 
boolean dataarrive = true; 

//Leest de stand van de drukknop 
int lidswitchstate = 0;        
int startswitchstate = 0;
int resetswitchstate = 0;  

//Functie om naar de I/O expander te schrijven  
void PCF8574AN_Write(int adress, byte data) {
  Wire.beginTransmission(adress);
  Wire.write(data);
  Wire.endTransmission();
  delay(5);
}

//Functie om de I/O expander te lezen
byte PCF8574AN_Read(int adress) {
  byte dataByte=0xff;
  Wire.requestFrom(adress,1);
  if(Wire.available()){
    dataByte=Wire.read();
    dataarrive=true;
    }
  else {
    dataarrive=false;
  }
  return dataByte;
}

void setup(){

  lcd.begin(16, 2); //Geeft het aantal kolommen en rijen op van het LCD weer     
  lcd.clear();      //Verwijderd de weergegeven text op het LCD 
  
  //Initialiseer de inputs
  pinMode(startswitch, INPUT); 
  pinMode(lidswitch, INPUT); 
  pinMode(resetswitch, INPUT); 

  //Initialiseer de outputs 
  pinMode(ledred, OUTPUT);
  pinMode(ledyellow, OUTPUT);
  pinMode(ledgreen, OUTPUT);
  pinMode(ledblue, OUTPUT);
  pinMode(magnetpin, OUTPUT); 


  
  //Alle LED's uit: HIGH betekent LOW. Dit is de PCF8474 I/O expander
  digitalWrite(ledred,HIGH);  
  digitalWrite(ledyellow,HIGH);
  digitalWrite(ledgreen,HIGH);
  digitalWrite(ledblue,HIGH); 
  digitalWrite(magnetpin,HIGH); 
 
  
  Wire.begin();            //Join the i2C bus
  Serial.begin(9600);
  PCF8574AN_Write(PCF8574AN,0x38);

  //Geeft na elke meting het aantal goedkekeurde en foutgekeurde rotoren weer 
  lcd.setCursor(0,0);
  lcd.print("Amount of rotors:");
  lcd.setCursor(0,1); 
  lcd.print("OK:....Not OK:..."); //Dit wordt dus na elke meting +1 bij OK of +1 bij Not OK
 
 }

void loop() { 
  byte data;
  data=PCF8574AN_Read(PCF8574AN);

  //Wanneer een detectiesensor actief wordt, zal dit worden weergegeven op het LCD en met een LED 
  if (dataarrive) {
    if(bitRead(data,1))
     digitalWrite(ledblue,LOW);                 
    else
     lcd.clear(),lcd.print("Rotor1 detected"), lcd.setCursor (0,1), lcd.print("Close lid"), digitalWrite(ledblue,HIGH); 
 
      if(bitRead(data,2))
      digitalWrite(ledblue,LOW);
    else 
     lcd.clear(), lcd.print("Rotor2 detected"), lcd.setCursor (0,1), lcd.print("Close lid"), digitalWrite(ledblue,HIGH); 
   
    if(bitRead(data,3))
      digitalWrite(ledblue,LOW); 
    else 
      lcd.clear(),lcd.print("Rotor3 detected"), lcd.setCursor (0,1), lcd.print("Close lid"), digitalWrite(ledblue,HIGH);
   
}
Als één van de 3 detectiesensoren én de lidswitch bediend is, mag de startknop worden ingedrukt om de meting te starten.   
lidswitchstate = digitalRead(lidswitch);  
if ((lidswitchstate == HIGH) && (bitRead(data,1) == LOW) || (bitRead(data,2) == LOW) || (bitRead(data,3)) == LOW){
delay(50); 
lcd.clear(); 
lcd.setCursor(0,0); 
lcd.print("Press Start button"); 
delay(500); 

} else {
return 0;
}

Ik hoop dat jullie mij verder kunnen helpen met de code.

Lars

Stappenplan.pdf (198 KB)

Hoi larsouderengerink, welkom !

Zoiets als jouw stappenplan zien we hier eigenlijk nooit voorbij komen. Ik neem aan dat je dat tijdens je opleiding hebt geleerd, maar ik vind het een mooi begin. Misschien omdat ik mezelf iets vergelijkbaars heb aangeleerd.

Ik ga je wat dingen laten zien die mij zijn opgevallen in je code, ik weet nu nog niet of je daarmee je probleem gaat oplossen.

Ten eerste cmpileert je code niet, omdat je wat // bent vergeten in commentaar regels, maar ook omdat je in je loop (die een void is) een return doet en daarbij een nul meegeeft; dat kan niet.

Tijdens setup kom ik dit tegen:

  //Alle LED's uit: HIGH betekent LOW. Dit is de PCF8474 I/O expander
  digitalWrite(ledred,HIGH);

Ook al zal dit ongetwijfeld correct zijn, het leest mij niet zo heel fijn. Daarom zou mijn voorkeur zijn om anders om te gaan met die inverterende uitgang van je PCF.

Heb je dit al eens overwogen ?

  //Alle LED's uit: De PCF8474 I/O expander inverteert, dus geinverteerd aansturen met een !
  digitalWrite(ledred,!LOW);

Uiteraard heb ik voor ik dat schreef, heel even gekeken of de IDE dit wel toestaat, en dat gaat prima.

Een stukje verderop zie ik denk ik waar je vraag over gaat. Je gaat namelijk al wat op je LCD zetten over het aantal rotors, terwijl je nog in setup zit. Aangezien jij bezig bent met je opleiding, ben ik ook wat strenger naar jou als iemand die bij wijze van hobby een beetje zit te prutsen ;).

Je hebt al een functie gebruikt om de expander af te handelen. Daarom zou ik zeggen: doe het printen naar je scherm ook in een aparte functie. Of was dat toevallig eigenlijk al de bedoeling en heb je wat overgeslagen ?

Veel verder ben ik nu nog niet gekomen, maar ik zie al veel onvolkomenheden in je code.

Daarom geef ik de thread nu terug aan jou, zodat je je eigen code nog eens goed kunt bekijken. Ik weet natuurlijk niet of er ergens iets is fout gegaan tijdens het kopieren naar het forum door jou, of wellicht ook tijdens het kopieren naar de IDE bij mij.

Overigens: Als de tekst over het aantal rotors wel zo bedoeld is, dan moet je ons vertellen wat er precies op je schermpje staat dat er niet thuis hoort.

Hoi,

bedankt voor je bericht.
Alleen het lukt nog steeds niet.
Wanneer de sensoren een magnetisch veld detecteren is het de bedoeling dat er een blauwe led gaat branden en op het LCD moet worden weergegeven om welke rotor het gaat. Nu geeft het LCD het juist aan maar de blauwe LED gaat maar bij één detectiesensor branden. Als ik bij de andere 2 sensoren een groene en een rode LED wil laten branden gaat dit wel goed. Maar bij alle 3 een blauw LED niet. Het gaat hier om dit stukje code:

void loop() {
  byte data;
  data=PCF8574AN_Read(PCF8574AN);

  //Wanneer een detectiesensor actief wordt, zal dit worden weergegeven op het LCD en met een LED 
  if (dataarrive) {
    if(bitRead(data,1))
     digitalWrite(ledblue,LOW);                 
    else
     lcd.clear(),lcd.print("Rotor1 detected"), lcd.setCursor (0,1), lcd.print("Close lid"), digitalWrite(ledblue,HIGH); 
 
      if(bitRead(data,2))
      digitalWrite(ledblue,LOW);
    else 
     lcd.clear(), lcd.print("Rotor2 detected"), lcd.setCursor (0,1), lcd.print("Close lid"), digitalWrite(ledblue,HIGH); 
   
    if(bitRead(data,3))
      digitalWrite(ledblue,LOW); 
    else 
      lcd.clear(),lcd.print("Rotor3 detected"), lcd.setCursor (0,1), lcd.print("Close lid"), digitalWrite(ledblue,HIGH);
delay(1000);

  
}

Verder doet het programma niks met mijn If functie. De bedoeling is dat wanneer de drukknop én één van de 3 detectiesensoren een signaal doorgeeft, er op de startknop mag worden gedrukt. Op het LCD wordt direct weergegeven dat er al op de startknop gedrukt mag worden.

Lars

Polariteitsmeter_Arduino.ino (3.43 KB)

Hoi.

Je maakt je er nu een beetje te gemakkelijk vanaf. De code die je geplaatst hebt, is een knipsel van het geheel. Daar kan niemand iets mee.

Als je geholpen wil worden, moet je alles wat relevant is aanleveren, zoals je dat in je eerste post ook deed voor zover ik kan zien.

Ik neem aan dat je data in een array moet binnen komen ? In dat geval moet je dat dus ook als een array behandelen. Dat was dus een foute aanname...

[edit] Ik zag dat je aangehangen bestand wat groot was voor wat je binnen je post liet zien. Ik prefereer om niet onnodig dingen te downloaden, maar in dit geval heb ik dat toch gedaan. Daar zit zo te zien wel je hele sketch in.

Daarin kan ik zien dat je wel iets gedaan hebt met mijn tip over het inverteren van de PCF chip, maar alleen de blauwe LED word nu laag gemaakt en de rest van de LEDs niet (wanneer die aan de PCF hangen).

   if(bitRead(data,1))
     digitalWrite(ledblue,LOW);

Dat werkt natuurlijk, maar in de zin van mijn tip, zou het dan dus worden:

   if(bitRead(data,1))
     digitalWrite(ledblue,!HIGH);

Ik krijg geen compiler fouten meer, maar de PCF library heb ik hier niet geïnstalleerd.

Ik zie wat ontbrekende {curly braces}. Dat compenseer je door van alles op 1 regel te proppen, en er komma's tussen te zetten. Dat verdient geen hoofdprijs.

Je hebt een display aan je installatie hangen. Dat display is van belang voor je apparaat, maar je kunt het ding ook 'misbruiken' als debug hulpmiddel. Dus stuur eens wat van de data waar je op dat moment mee aan het stoeien bent naar dat display. Want hoe weet je nu wat er in dat uitgelezen bitje zit, en of er überhaupt wel iets is binnen gekomen ? Moet je 'm misschien wel wat vaker uitlezen dan je nu doet, maar dat dient een goed doel. Of als je daar van in de war zou raken, stuur het dan via de seriële poort naar je pc. Dan kun je in ieder geval meekijken met wat je Arduino allemaal voorbij ziet komen. Wanneer je klaar bent met het debuggen en alles werkt zoals bedoeld, kun je dat hulpmiddel weer uitschakelen door er commentaar regels van te maken. Op die manier kun je bij een volgende keer dat je met de code aan de slag kunt, heel eenvoudig dat debug hulpmiddel weer inschakelen.

Ik zie ook 4 keer een delay(). Das jammer. [/edit]

de ifs gaan heel erg snel, en omdat je overal else hebt gebruikt zie je alleen de laatste. zet er om het te testen een paar delays in, en serial.prints in dan kun je zien welke regels gedaan worden.

Een beetje laat maar al dat moeilike gedoe met HIGH en LOW voor de leds te voorkomen kun je #define gebruiken.

#define LED_ON LOW
// optional
#define LED_OFF HIGH

En om de blauwe led te laten oplichten

digitalWrite(ledblue, LED_ON);

En twee opties voor het uitschakelen

digitalWrite(ledblue, LED_OFF);
digitalWrite(ledblue, !LED_ON);