I2C - Lezen van sensoren - hulp nodig.

Goede morgen,

Ik zal me snel even voorstellen, Ik ben Nick Bijl woon in de Provincie Drenthe en studeer (bijna klaar) elektronica niveau 4 aan het Drenthe College te Emmen.

Ik ben sinds kort meer geintereseerd geraakt voor Arduino, en ben bezig met om een klein testkastje te ontwikkelen voor verschillende PCB's op mijn stage plek bij Creacon Technologies/Prince Technologies.

Nu heb ik moeite om het i2c protocol te begrijpen, en na lang zoeken op de forums en het internet bedacht ik me maar eens om hier om hulp te vragen.


Okay, dan hier het idee. Binnen dit bedrijf zijn er meerdere pcb's die via het IC PCA8574 worden aangestuurd en uitgelezen, om te zorgen dat de pcb's werken voordat ze ingebouwt worden moeten deze even getest worden via sensoren. Voor deze aansluiting heb ik vijf draden beschikbaar, de 5Volt (zit op de 5v aansluiting van Arduino) de GND.. nja.. duidelijk. en dan hou ik de SDA/SCL & Interrupt over.

Hoe kan ik de sensoren nu uitlezen via deze lijnen (zitten 5 PCB's op aangesloten en allemaal doorgelust) ?

Verder worden deze sensoren getriggerd via solenoids die eroverheen bewegen, dit lukt wel zonder enige problemen.

indien er meer info nodig is valt dit vast wel te leveren!

Alvast bedankt, Nick Bijl

Welkom op hey nederlandstalige gedeelte van het forum. I2C heeft normaal alleen maar SDA en SCL. Daar er ook een interrupt is denk ik dat die dient om te verwittigen dat data klaar staat. Effe ter verduidelijking I2C is een master slave protocol. De slaaf mag de meester niet aanspreken zonder dat de meester daarom heeft gevraagd. So kan de meester slaaf per slaaf aanspreken en vragen "heb jij mij iets te zeggen". Een slaaf wordt herkend door zijn adres. Dus elke slaaf moet een ander adress hebben. Anders beginnen 2 slaven (als antwoord op de meester) door elkaar te praten en dan snap je er niks meer van. Deze manier van communiceren (meester vraagt slaaf per slaaf iets) noemt men pollen. Pollen betekend dus ook altijd een beetje te laat en veel bezig voor niks. Waarschijnlijk zijn de interrupts er om die tekortkoming van pollen op te lossen. Het laat de slaaf toe om via een ander kanaal de meester te verwittigen dat hij/zij iets te zeggen heeft. Vergelijk het met de vinger opsteken in de klas. De interrupts kunnen dus wel allemaal op 1 pin (maar dan moet je alle slaven vragen wie wat te zeggen heeft) maar kunnen ook elk op hun eigen pin (dan weet je welke slaaf iets te zeggen heeft).

Ik hoop dat ik het wat duidelijker gemaakt heb. Met vriendelijke groet Jantje

Deze engelstalige website beschrijft zo ongeveer alles wat je van I2C nodig hebt.

De pinnen die gebruikt moeten worden zijn afhankelijk van het type arduino.

er bestaat een prima library voor (wire) om i2c te kunnen bewerken. de PCF8574 hebben drie adreslijnen waardoor je er 8+8 (Aversie) aan kunt hangen. De interuptlijn verbinden met een interupt van de arduino. als de toestand van een pinnetje van je PCF verandert wordt de interupt lijn aan gezet. Dat is het teken dat de arduino moet gaan pollen om te kijken welk IC er verandert is. zo gauw je deze leeg leest dan verdwijnt de interupt ook. paar weerstandjes en een stukje software is voldoende.

met de 5Volt even opletten dat je niet teveel stroom uit je arduino trekt, dus liever de arduino voeden vanuit een externe voeding van 7Volt of hoger op Vi. zoek eens op arduino 8574.

Je kunt met processing ook nog een mooi beeld op de PC krijgen, of ook met I2C een paar ledjes aan laten gaan via een of meerdere PCF8574 (daar heb je er toch genoeg van)

Bedankt Jantje, Rob en Shooter, Ik zal de documentatie en tips eens even doornemen & gebruiken, indien ik weer vragen heb post hier ik wel weer!

  • Hendrik

Okay, ben weer een stapje verder en het is me allemaal ‘iets’ meer duidelijk geworden :slight_smile:

Maar nu heb ik dus mijn code:

// Add libraries.
#include <Wire.h>
#include <avr/io.h>
// Define variables.
int button = 9;
int solPin = 13;


void setup()
{
  pinMode(solPin, OUTPUT);
  pinMode(button, INPUT);
  digitalWrite (button, LOW);
  Wire.begin();
  Serial.begin(115200); // Enable Serial communications.
  Serial.println("Program enabled");
}

void loop()
{
  Wire.requestFrom(0x21, 8);


  if (digitalRead(button) == HIGH)     //When button is pressed, start program.
  {
    Serial.println("Program starting test");
    delay(1000);

    digitalWrite(solPin, HIGH);        //Enable Solenoid.
    Serial.println(" Solenoid HIGH");  //Print to serial monitor.

    char I2Cdata1 = Wire.read();       //Read serial data.
    delay(10);                         //Wait.
    Serial.print("I received: ");      //Print to serial monitor.
    Serial.println(I2Cdata1 , HEX);    //Print to serial monitor.
    delay(1000);                       //Wait --- seconds. (NEEDS TO BE DEFINED)

    digitalWrite(solPin, LOW);         //Disable Solenoid.
    Serial.println(" Solenoid LOW");   //Print to serial monitor.

    I2Cdata1 = Wire.read();            //Read serial data.
    delay(10);                         //Wait.
    Serial.print("I received: ");      //Print to serial monitor.
    Serial.println(I2Cdata1 , HEX);    //Print to serial monitor.

    delay(1000);                       //Wait --- seconds. (NEEDS TO BE DEFINED)
    Serial.println("Program finished test");
    Serial.println("---------------------");
  }
  else                                 //If button is not pressed, turn OFF.
  {
    digitalWrite(solPin, LOW);         //Disable Solenoid.
  }
  delay(10);                           //Wait.
}

En nu is mijn vraag hoe ik dan in dit geval, de sensoren op 0x21 kan testen.
Op dit moment worden ze wel al uitgelezen en worden de waardes op X1 & X2 HEX: FFFF FFFF (Bij geen cover) en: FFFF FFFE bij X1 (bij trigger) en: FFFF FFFD bij X2 (bij trigger) op het moment dat deze appart getriggerd worden.
Als deze bijde getriggerd zijn worden het FFFF FFFC.

Maar hoe kan ik nu dan zeggen dat bijvoorbeeld bij FFFF FFFC de print “Goed” is en bij FFFF FFFF “Fout”.

  • Hendrik

http://www.arduino.cc/en/Reference/If

en de If statement zou ik dan moeten gebruiken als.. if((I2CData1) == FFFFFFFF) ? Verder merk ik dat als ik de I2CData lees... ik 2x dezelfde data krijg met de Solenoid hoog en laag. Leest hij heer maar 1x de data aan het begin? of staat het verkeerd in de code?

er staat toch twee keer een read instructie dus ja hij leest het twee keer. en je zult dus moeten testen of de data klopt met solenoid en een keer zonder solenoid. en daarna met solenoid nog een keer. dan weet je tenminste dat er wat gebeurt. jouw if klopt wel hoor (nou ja er moet wat voor die effen, zoek lekker zelf) en dus moet er drie keer een vlag aangezet worden, en op het eind moeten alledrie de vlaggen goed zijn. dus if (vlag1 && vlag2 && vlag3) dan prima groene lamp aan anders rode lamp aan.

Hey bedankt voor de hulp iedereen, Ik heb hem nu grotendeels aan de praat en kan niet anders zeggen dat ik steeds meer geboeit raak door Arduino, iets wat ik inderdaad op school nooit echt had... (maar ja, het is wel school...)

Ik miste in mijn programma alleen nog even een char I2Cdata1 = Wire.read(); om hem de 2de keer te lezen, ik dacht dat ik die met I2Cdata1 = Wire.read(); ook weer opnieuw opriep.