Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

example for I2C sensor reading #54

Closed
adrianardu opened this issue Dec 10, 2015 · 5 comments
Closed

example for I2C sensor reading #54

adrianardu opened this issue Dec 10, 2015 · 5 comments

Comments

@adrianardu
Copy link

Hi,
finally after the whole installations and configurations I am able to run you examples like the yun_potentiometer. They run great and I love the fast response which is without crossbar/autobahn not possible.
Now I want to implement my I2C sensors. Unfortunetely I completly failed with this target.
I tried it with sysex commands, but due to lags of information which (and how) parameters I have to use to read for example the address 0x58, I can't continue.

Thanks for your help.

@oberstet
Copy link
Contributor

Could you describe the parts of your setup in detail? Eg are you using AutobahnJS or AutobahnPython on the Yun? What library to talk to the Arduino side of the Yun. etc etc Ideally, also post some code - even non-working.

@adrianardu
Copy link
Author

Mainly I go through the detailed setup described at the crossbar.io website (The Quick Setup makes problems with the SD card).
I installed node, node serialport on the yun. arduino-firmata and autobahn on centos (where I also installed crossbar.io) and then copied it to the yun (the node modules).
On the MCU I installed the StandardFirmataYun.ino (from 07.11.15).

For using sysex commands I add to Firmata (in the sysexCallback function):

switch(command){
  case 0x01: // LED Blink Command
    if(argc < 3) break;
    byte blink_pin;
    byte blink_count;
    blink_pin = argv[0];
    blink_count = argv[1];
    delayTime = argv[2] * 100;
  argv[1] = 22;
    pinMode(blink_pin, OUTPUT);
    byte i;
    for(i = 0; i < blink_count; i++){
      digitalWrite(blink_pin, true);
      delay(delayTime);
      digitalWrite(blink_pin, false);
      delay(delayTime);
    }
    Firmata.sendSysex(command, argc, argv); // callback
    break;

I called it with node at the command line with:

arduino.sysex(0x01, [22, 6, 6], function(r2) { 
    arduino.on('sysex', function(e){
    console.log("Data 2: ", e.command);
    console.log("data    : " + JSON.stringify(e.data));

This code works and let the led 13 blink.

I thought that I can call the I2C commands in the same way:

var device_port = '/dev/ttyATH0';
var firmata = require('arduino-firmata');
var arduino = new firmata();
arduino.on('connect', function(){
  arduino.pinMode(3, firmata.PIN_MODE_I2C);
  arduino.pinMode(2, firmata.PIN_MODE_I2C);
  arduino.sysex(0x78);  // 0x78 = I2C_CONFIG
  arduino.sysex(0x76, [0x58, 'I2C_READ'], function(x){   //0x76 = I2C_REQUEST
      arduino.on('sysex', function(e){
    console.log("Data: ", e.command);
     console.log("data    : " + JSON.stringify(e.data));
  });
  });
   console.log("connected");
});

arduino.connect(device_port);

I'm sure that the I2C sensor is working, because I tested it with another yun with standard setup.
unfortunately I have no idea how to parameterize sysex. And also If my logic is correct that I have to switch pin 2 and 3 to I2C Mode then enable I2C with I2C_CONFIG and then use command I2C_REQUEST with I2C_READ as Mode.

Here is the code with which I succesfully work without firmata (standard yun setup with bridge.h wire.h yunserver.h yunclient.h etc.)

Wire.beginTransmission(hytaddr[i]); // Begin transmission with given device on I2C bus
      Wire.requestFrom(hytaddr[i], 4); // Request 4 bytes
      // Read the bytes if they are available
      // The first two bytes are humidity the last two are temperature
      if(Wire.available() == 4) 
      {
        int b1 = Wire.read();
        int b2 = Wire.read();
        int b3 = Wire.read();
        int b4 = Wire.read();
        Wire.endTransmission(); // End transmission and release I2C bus
        // combine humidity bytes and calculate humidity
        int rawHumidity = b1 << 8 | b2;
        // compound bitwise to get 14 bit measurement first two bits
        // are status/stall bit (see intro text)
        rawHumidity = (rawHumidity &= 0x3FFF);
        humidity = 100.0 / pow(2,14) * rawHumidity;
        // combine temperature bytes and calculate temperature
        b4 = (b4 >> 2); // Mask away 2 least significant bits see HYT 221 doc
        int rawTemperature = b3 << 6 | b4;
        temperature = 165.0 / pow(2,14) * rawTemperature - 40;

Thank you for your help

@oberstet
Copy link
Contributor

Thanks for the detailed info!

I thought that I can call the I2C commands in the same way

Yes, this is actually a question. I don't have an answer as I haven't played with I2C stuff. I'd ask in the Firmata community / mailing list about that. Because this question/issue isn't related to Autobahn/Crossbar.io

If you have working code to talk to I2C from Firmata/node, adding that to the AutobahnJS/Firmata example will be trivial.

The real question hence is: "How do I talk I2C using Firmata from Node on the Yun?"

@adrianardu
Copy link
Author

Yes, this sounds like the real question.

@goeddea
Copy link
Contributor

goeddea commented Dec 14, 2015

Closing this as an issue, as it's not directly related to Crossbar.io itself.

@adrianardu - If you come up with a solution, then we'd be grateful if you could tell us about it (maybe with a minimal working example). We won't investigate this ourselves at the moment, but we'd certainly want to add it to the cookbook if you get it working.

@goeddea goeddea closed this as completed Dec 14, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants