Arduino uitlezen ZMD 31050 via I2C

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • __fred__
  • Registratie: November 2001
  • Laatst online: 13-10 12:06
Voor een doe het zelf projectje (PID regelen van mijn espressomachine) ben ik aan het stoeien geslagen met een arduino en deze thermokoppel module. De module bevat o.a. een ZMD 31050. Deze chip is uit te lezen via I2C. Dat uitlezen zou op moeten leveren:
  • Byte 0 MSB voltage thermokoppel
  • Byte 1 LSB voltage thermokoppel
  • Byte 2 MSB PT 1000 referentietemperatuur
  • Byte 3 LSB PT 1000 referentietemperatuur
Volgens het eerste datasheet mag je gewoon op adres 0x78 4 bytes tegelijk lezen, wat bovenstaande bytes oplevert. Dat doe ik dus ook met de volgende code:

C++:
1
2
3
  Wire.requestFrom(0x78, 4);
  int thermalVoltage = (Wire.receive() << 8) + Wire.receive();
  int thermalEquilibrium = (Wire.receive() << 8) + Wire.receive();


Echter dit levert thermalVoltage == thermalEquilibrium op. Het lijkt dus alsof slechts de eerste twee bytes worden gelezen. Ik heb ook al gecontroleerd of er daadwerkelijk 4 bytes worden gelezen (return waarde requestFrom) en of bytes beschikbaar zijn (Wire.available()) maar dit lijkt allemaal zo te zijn. Er worden gewoon 4 bytes gelezen van de module, maar somehow zijn de eerste twee gelijk aan de laatste twee.

ra ra hoe kan dat?

Acties:
  • 0 Henk 'm!

Verwijderd

__fred__ schreef op zondag 08 november 2009 @ 23:37:
Er worden gewoon 4 bytes gelezen van de module, maar somehow zijn de eerste twee gelijk aan de laatste twee.
Concludeer je dat naar aanleiding van je code of heb je dit op een andere manier vastgesteld? De i2c lib van Arduino wordt volgens mij vrij veel gebruikt en ik kan me daarom niet voorstellen dat er een fout in dergelijke basis functionaliteit zou zitten. Verder lijk je de lib ook correct te gebruiken. De grote vraag is dus; wat gaat er daadwerkelijk over het lijntje en komt dat overeen met jou resultaten?

Acties:
  • 0 Henk 'm!

  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 12-10 06:44

Sprite_tm

Semi-Chinees

Even onafhankelijk van je probleem: volgens mij is de volgorde waarop de variabelen geevalueerd worden in een expressie (op and/or-operaties na) in C niet gedefinieerd. Je hebt dus geen enkele garantie dat je eerste Wire.receive voor de tweede uitgevoerd word; ik zou dus zowiezo voor de portabiliteit en netheid dat even in losse variabelen stoppen.

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


Acties:
  • 0 Henk 'm!

  • Cassettebandje
  • Registratie: Juli 2002
  • Laatst online: 16:53

Cassettebandje

SA-C90 TDK

Wire.receive returnt een byte. Als je dan vervolgens die byte 8 posities shift hou je niets meer over.
Oplossing:
C++:
1
2
3
  Wire.requestFrom(0x78, 4);
  int thermalVoltage = (((int)Wire.receive()) << 8) + ((int)Wire.receive());
  int thermalEquilibrium = (((int)Wire.receive()) << 8) + ((int)Wire.receive());

Acties:
  • 0 Henk 'm!

  • __fred__
  • Registratie: November 2001
  • Laatst online: 13-10 12:06
Hmmm. Ik zal even wat meer toelichten:

Wire.requestFrom(0x78, 4) retourneert het getal vier. Dit lijkt toch alsof de chip 4 bytes in die read request terug geeft. Als we even de shifts buiten beschouwing laten, werkt de volgende code ook niet:

C++:
1
2
3
4
5
6
7
8
int count = Wire.requestFrom(0x78, 4); 
byte buf[4];

for (int i=0; i < count; i++)
{
     if (Wire.available())
        buf[i] = Wire.receive();
}


dit levert op buf[0] == buf[2] en buf[1] == buf[3];

Ik kan natuurlijk altijd een usb naar i2c converter kopen en de signalen gaan bekijken, maar als ik wat simpels over het hoofd zie, dan is het wat zonde.

Acties:
  • 0 Henk 'm!

  • Mr_gadget
  • Registratie: Juni 2004
  • Laatst online: 14-10 13:04

Mr_gadget

C8H10N4O2 powered

Dan kan je eventueel kijken naar een buspirate, die dan kan van alles uitlezen :)

Ben zelf bezig een gyro uitlezen via i2c met arduino. Misschien kan je het volgende verhelderen: hoe ziet het met de hex adressen? Ik zie af en toe in andere code dat het eerste cijfer er af wordt gehaald ofzo, kan dat kloppen? Ik heb zelf het adres 1101 + 000 en 1 omdat ik wil lezen. Kan ik dan gewoon Wire.requestFrom(0xA1, 8 ) doen?

Acties:
  • 0 Henk 'm!

  • __fred__
  • Registratie: November 2001
  • Laatst online: 13-10 12:06
Niet zozeer het eerste cijfer eraf slopen als wel een bitshift (alle bitjes opschuiven).

Een 8 bits adres krijg je door de 7 bits naar 1positie naar links te schuiven en er afhankelijk van de operatie (read = 1, write = 0) nog deze RW bit erbij op te tellen.

Andersom als je een 8 bits adres in een documentatie leest, dan kun je er een arduino adres van maken door een bit shift naar rechts. Een eventuele read write bit valt er dan vanzelf af.
Pagina: 1