[Solved] Analog input with MOD-IO in python

Started by marcbas2, February 06, 2013, 07:31:21 PM

Previous topic - Next topic

marcbas2

Hi,
I use a MOD-IO (4 relays) with a raspberry pi as shown here and I can easily control all relays the way I want with Python.
However, I can not read analog inputs. The README file in firmware archive don't help me and my program don't work.
Would it be possible to show me a brief example of functional code in python?
Google finds me lot of examples of using relay, none with analog inputs.
Thanks,
Regards,

Marc

xenoxaos

From the documentation that comes with it.
Quote2) Get the voltage applied to one of the analogue inputs of the board. The board features four 10bit resolution analogue inputs (input voltages from 0 - 3.3V) and each of them is read with a separate command. Command should have the following common format:
   
   ************************************
   S aaaaaaaW cccccccc P S aaaaaaaR dddddddd 000000dd P
   ************************************
   
   Where
   S - start condition
   aaaaaaa - slave address of the board
   W - write mode, should be 0
   cccccccc - command code, should be 0x30 for AIN1, 0x31 for AIN2, 0x31 for AIN3, 0x31 for AIN4.
   P - Stop condition
   R - read mode, should be 1   
   dddddddd 000000dd – Little Endian (LSB:MSB) 10bit binary encoded value corresponding to the input voltage. Range is 0 - 0x3FF and voltage on the pin is calculated using the following simple formula: voltage = (3.3 / 1024) * (readvalue) [Volts]
   
   Note: Successive readings from the board without reissuing the command code will not get an updated value of the voltage (i.e. the user will read the same value) until another command is issued.

So, pretty much write to the MOD-IO and tell it you want to read an analog value, wait a bit, then read from it.  My guess is the command codes are actually 0x30-0x33 for AIN1-4,

And there's a reference for i2c in python... http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc

So, without having much python experience, and not having a MOD-IO it would probably be something like...
bus.write_byte(address,0x31)
value_of_ain_LSB = bus.read_byte(address)
value_of_ain_MSB = bus.read_byte(address)

but that's just a guess...



marcbas2

Thank you for the answer.
In fact, I was able to move a little. The analog read method "works" but only the first time.
In the code below, I can now read the value of the input, but it only works 3 or 4 times, and I do not understand what is happening.
If I reset the MOD-IO card, it works again 3 or 4 times and again the values ​​are zero and the relay no longer works.
If I quit the program and restart, it does not work until I reset the card.

The python program:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import smbus
import time
bus = smbus.SMBus(1)
address = 0x58

def relay():
    """start relay 1 for 1s"""
    print "Starting relay"
    bus.write_byte_data(address, 0x10, 0x01)
    time.sleep(1)
    bus.write_byte_data(address, 0x10, 0x00)
    time.sleep(1)
    print "Relay stopped"

def read_analog1():
    """ read first analog input"""
    value = bus.write_byte_data(address, 0x30, 0x01)
    time.sleep(1)
    value=bus.read_byte_data(address, 0x30)
    time.sleep(1)
    return value


while True:
    relay()
    value = read_analog1()
    print "Input 1:", value


The result:

Starting relay //relay working
Relay stopped
Input 1: 250   <--- analog input value "almost correct"
Starting relay //relay working
Relay stopped
Input 1: 245   <--- analog input value correct
Starting relay //relay working
Relay stopped
Input 1: 245   <--- analog input value correct
Starting relay //relay NO LONGER working
Relay stopped
Input 1: 0   <--- analog input value INcorrect
Starting relay //relay NO LONGER working
Relay stopped
Input 1: 0
Starting relay //relay NO LONGER working
Relay stopped
Input 1: 0
Starting relay //relay NO LONGER working
Relay stopped
Input 1: 0      <---- manual card reset
Starting relay  // relay
Relay stopped   // relay work again
Input 1: 250   <--- analog input value "almost correct"
Starting relay //relay NO LONGER working
Relay stopped
Input 1: 0   <--- analog input value INcorrect
Starting relay //relay NO LONGER working
Relay stopped



Do I something wrong?

marcbas2

Hi,
I really can not ...
When I only use relays, no problem, but when I try to use analog or digital inputs, nothing works after a few loops.
I have other I2C elements thats works (temperature sensors, pressure measurements or humidity) so I suspect the MOD-IO board.
Nobody else has problems with analog inputs on this board?

selfbg

#4
Hi Marc,

You need only one command.
sudo modprobe -r i2c_bcm2708 && sudo modprobe i2c_bcm2708 baudrate=50000

This will set i2c baudrate to 50kHz. Current firmware does not support clock stretching and apparently 40us are not enough for ADC reading. After that you could use following:

import smbus
bus = smbus.SMBus(0)
print bus.read_i2c_block_data(0x58, 0x30, 2)


Hope this will help :)

Best regards,
Stefan/Olimex

marcbas2

It helps, for sure!
I can finally read the correct input values ​​and advance in my project. \o/
A big thank you for this vital information.

Marc