tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

New Version of Nanpy 0.9

Wed May 07, 2014 4:25 pm

I've just managed to install Nanpy-v0.9 and get it working.

Email me at arduinolink@gmail.com and will send the new installation instructions.

I will upload to the forum soon but formatting will take a little longer.

Regards

Tony Goodhew

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Wed May 07, 2014 4:28 pm

I've just managed to install Nanpy-v0.9 and get it working.

Email me at arduinolink@gmail.com and will send the new installation instructions.

I will upload to the forum soon but formatting will take a little longer.

Regards

Tony Goodhew

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Wed May 07, 2014 4:31 pm

New instructions are available for the new version of Nanpy -v0.9. Email me at arduinolink@gmail.com if you would like a copy. I will post instructions once I have reformatted them.

Regards

Tony Goodhew

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Wed May 07, 2014 5:50 pm

Using Nanpy-0.9 to connect your RPi to an Arduino

Preparing the SD card – Version 4 – 7 May 2014 – by Tony Goodhew

You a need a 4 GB class 4 card (slow). Copy the latest version of Raspbian Wheezy onto it and expand the root partition. Reboot the Pi.
It’s best to do sudo apt-get update and sudo apt-get upgrade now. The second takes some time!

Install setuptools
You need python setuptools to install nanpy on your card. This is not in the current distribution. You can download it from the Web.

Start Midori and type in the URL box https://pypi.python.org/pypi/setuptools ... #downloads

Scroll down to the Linux instructions and then on to downloads. We want the file:
setuptools-0.6c11-py2.7.egg
Click on it and you will be asked to open or download. Click on SAVE. It downloads very quickly.

Close Midori and you should see the egg file in the pi directory.
Type into the LX terminal:
sudo sh setuptools-0.6c11-py2.7.egg
This is a very quick installation.

Install the Arduino software
Still in the LX Terminal.
Type in the the following command:
sudo apt-get install arduino
Answer ‘Y’ when asked if you want to continue. This installation takes some time…..
You can now program your Arduino from the Arduino IDE.

Install Nanpy
The next step is to download the nanpy files:

Using your Midori navigate to https://pypi.python.org/pypi/nanpy
and download nanpy-v0.9.tar.gz and nanpy-firmware-v0.9.tar.gz This downloads the zipped directories. Now unzip them using LX terminal.
gunzip nanpy-v0.9.tar.gz # To unzip it
tar –xvf nanpy-v0.9.tar # To untar it
gunzip nanpy-firmware-v0.9.tar.gz # To unzip it
tar -xvf nanpy-firmware-v0.9.tar # To untar it

This creates 2 new folders called nanpy-0.9 and nanpy-firmware-v0.9.
Make a new directory with:
mkdir sketchbook
copy the nanpy directory into the sketchbook directory:
cd nanpy
cp –avr nanpy /home/pi/sketchbook

Start the Arduino application and select sketchbook as the new directory for Arduino sketches.
Connect your Arduino via a POWERED USB HUB at this point.
In the Arduino application navigate to:
/pi/nanpy-firmware/NanpyNanpy.ino and click the OPEN button.
This loads the Firmware for the Arduino. Under the Edit menu is a circular button with right pointing arrow. Click this button to compile and upload the firmware.
(If you get an error message ‘Serial port not found’ then select /dev/ttyACM0.)
Close the Arduino IDE.

This section loaded the Arduino part of nanpy into the Arduino. You may need to do it again if you corrupt the part of nanpy now in the Arduino or if you re-program it from the Arduino IDE.

Using LX terminal type:
cd nanpy
sudo python setup.py install
This adds the addition functionality to Python 2.7

This adds the RaspPi part of nanpy to Python2 and only needs to be done once. You can now use the Arduino as an I/O board for the Pi. This adds 19 extra I/O pins – 6 can be used for 10-bit analog inputs(range 0-1023) and 6 as PWM outputs (range 0-255). (Do not use pins 0 or 1 – Tx and Rx to Pi.)

Testing

The Arduino really needs to be connected via a powered USB hub so that it does not take too much power from the RPi. (NB All sensors & outputs add to the current drain.)

On your Arduino connect an LED in series with a resistor (about 330 Ohms for protection) between pin 10 and ground. The longer lead of the LED, the anode, goes towards pin10 and the shorter, the cathode, towards GND. Pin 10 allows PWM (Pulse Width Modulation) – marked with ‘~’.

From LXED start LXTerminal and type: sudo idle
(With sudo you can run the program from the Run menu in Idle)
Click on File, then New window. Then type in the following program into the new window:

Save and run the program from the idle menu.

#!/usr/bin/env python
#LED on pin 10 with 330 ohm resistor
from nanpy import (ArduinoApi, SerialManager)

connection = SerialManager()
a = ArduinoApi(connection=connection)

from time import sleep

a.pinMode(10, a.OUTPUT)
print"Starting"
while 1:
a.digitalWrite(10, a.HIGH)
print"ON"
sleep(0.5)
a.digitalWrite(10, a.LOW)
sleep(0.5)
print"OFF"

--------------------------------------------------------------------------------------

#!/usr/bin/env python
#Read values from Analogue pin A0
# 10K ohm potentiometer on A0
from nanpy import (ArduinoApi, SerialManager)

connection = SerialManager()
a = ArduinoApi(connection=connection)

from time import sleep

pot = 14 # Pot on A0 - Anaglog input

print"Turn the pot - Analogue input - 10 bit"
for i in range(0,40):
val = a.analogRead(pot) # Analog input
print val
sleep(0.3)

Problem: If you pull the USB cable out of the Arduino while the Pi is controlling it you may need to re-boot the Pi before it will re-connect. You may also need to re-do the instructions at the bottom of page 1 if the firmware gets corrupted.

Thanks to Andrea Stagi for the Nanpy. See MagPi – issue 8, page 12

Main documentation for Nanp-v0.9 is at: https://pypi.python.org/pypi/nanpy/

Please let me know how you get on with this guide. Report errors or problems to: arduinolink@gmail.com

Regards

Tony Goodhew

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Wed May 07, 2014 7:25 pm

Sorry, the essential indents in the code does not show up in the previous post. I'll try again:

Save and run the programs from the idle menu.

Code: Select all

#!/usr/bin/env python
#LED on pin 10 with 330 ohm resistor
from nanpy import (ArduinoApi, SerialManager)

connection = SerialManager()
a = ArduinoApi(connection=connection)

from time import sleep

a.pinMode(10, a.OUTPUT)
print"Starting"
while 1:
      a.digitalWrite(10, a.HIGH)
      print"ON"
      sleep(0.5)
      a.digitalWrite(10, a.LOW)
      sleep(0.5)
      print"OFF"
--------------------------------------------------------------------------------------

Code: Select all

#!/usr/bin/env python
#Read values from Analogue pin A0
# 10K ohm potentiometer on A0
from nanpy import (ArduinoApi, SerialManager)

connection = SerialManager()
a = ArduinoApi(connection=connection)

from time import sleep

pot = 14 # Pot on A0 - Anaglog input

print"Turn the pot - Analogue input - 10 bit"
for i in range(0,40):
      val = a.analogRead(pot) # Analog input
      print val
      sleep(0.3)
Regards

Tony Goodhew

User avatar
bigdog
Posts: 3
Joined: Mon Apr 28, 2014 5:21 am
Location: Chicago

Re: Using an Arduino as a slave I/O board

Thu May 08, 2014 9:11 am

Thank you for being right on top of this Tony. I appreciate all the help you have provided. You must have been a good teacher. Unfortunately I am getting a new error after I type the following.

cp –avr nanpy /home/pi/sketchbook
cp: cannot stat `–avr': No such file or directory
cp: cannot stat `nanpy': No such file or directory

What exactly does the"-avr" command do? And can I just do a simple "mv" instead? Thanks in advance.

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Thu May 08, 2014 9:47 am

We need to copy the whole nanpy folder into the Arduino sketchbook folder.

http://www.cyberciti.biz/faq/copy-folde ... mand-line/
explains how it works. mv should manage to do the same job.

I think I missed a / further down between Nanpy and Nanpy.ino before you click OPEN button.

Thanks for the feedback - it all helps those who follow later.

Regards

Tony

ShaunVW
Posts: 37
Joined: Tue Aug 28, 2012 5:11 pm

Re: Using an Arduino as a slave I/O board

Thu May 15, 2014 2:15 pm

Thanks Tony for this, I think I got it all installed and ready to run.
Is it possible for you to give a small example of using the i2c in code?
Already know how to run the GPIO.
Been waiting for this! :D

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Thu May 15, 2014 5:59 pm

If you look at the Nanpy documentation on Github there is some example Python code:
https://github.com/nanpy/nanpy/blob/mas ... d_hello.py

Code: Select all

#!/usr/bin/env python


from nanpy import SerialManager
from nanpy.lcd import Lcd
from nanpy.lcd_i2c import Lcd_I2C


I2C = True




def hello():
    connection = SerialManager(sleep_after_connect=2)


    cols, rows = 16, 2


    if I2C:
        pins = [0x27, 2, 1, 0, 4, 5, 6, 7, 3, 0]  # "ebay" version
        lcd = Lcd_I2C(pins, [cols, rows], connection=connection)
        lcd.setBacklight(0)
    else:
        pins = [7, 8, 9, 10, 11, 12]
        lcd = Lcd(pins, [cols, rows], connection=connection)


    lcd.setCursor(0, 0)
    lcd.printString('hello')


if __name__ == '__main__':
    hello()
You will need the device address of your LCD_I2C and the internal pin numbers.

If you still cannot get it to work I suggest to email these guys, who wrote Nanpy, and ask for some help.
Andrea Stagi <stagi.andrea@gmail.com>

Regards

Tony

ShaunVW
Posts: 37
Joined: Tue Aug 28, 2012 5:11 pm

Re: Using an Arduino as a slave I/O board

Fri May 16, 2014 9:35 am

Thanks Tony for the example.
If anyone can help me further I would appreciate it.
I have previously tried emailing Andrea Stagi, although I don't believe I had a response.
I changed the pins setup very slightly, as the Enable and R/W seem to be swopped for my LCD, but it is set for 0x20 address.
I also enabled logging.
I'm not getting any output on my LCD. The LCD itself is lit up on reboot, but this is due to it getting power. The top line is filled with black blocks, the 2nd line is blank.
On running the program, there is no effect on the LCD.

This is my program:

Code: Select all

#!/usr/bin/env python


from nanpy import SerialManager
from nanpy.lcd import Lcd
from nanpy.lcd_i2c import Lcd_I2C
import logging
logging.basicConfig(level=logging.DEBUG)

I2C = True


def hello():
    connection = SerialManager(sleep_after_connect=2)


    cols, rows = 16, 2


    if I2C:
        pins = [0x20, 2, 1, 0, 4, 5, 6, 7, 3, 0]  
        lcd = Lcd_I2C(pins, [cols, rows], connection=connection)
        lcd.setBacklight(0)
    else:
        pins = [7, 8, 9, 10, 11, 12]
        lcd = Lcd(pins, [cols, rows], connection=connection)


    lcd.setCursor(0, 0)
    lcd.printString('hello')


if __name__ == '__main__':
    hello()

This is my output:

Code: Select all

^Cpi@raspberrypi ~ $ sudo python lcd.py
DEBUG:nanpy.serialmanager:opening port:/dev/ttyACM1 [115200 baud]
DEBUG:nanpy.serialmanager:sending:'Lcd_I2C\x00'
DEBUG:nanpy.serialmanager:sending:'0\x00'
DEBUG:nanpy.serialmanager:sending:'12\x00'
DEBUG:nanpy.serialmanager:sending:'new\x00'
DEBUG:nanpy.serialmanager:sending:'32\x00'
DEBUG:nanpy.serialmanager:sending:'2\x00'
DEBUG:nanpy.serialmanager:sending:'1\x00'
DEBUG:nanpy.serialmanager:sending:'0\x00'
DEBUG:nanpy.serialmanager:sending:'4\x00'
DEBUG:nanpy.serialmanager:sending:'5\x00'
DEBUG:nanpy.serialmanager:sending:'6\x00'
DEBUG:nanpy.serialmanager:sending:'7\x00'
DEBUG:nanpy.serialmanager:sending:'3\x00'
DEBUG:nanpy.serialmanager:sending:'0\x00'
DEBUG:nanpy.serialmanager:sending:'16\x00'
DEBUG:nanpy.serialmanager:sending:'2\x00'
DEBUG:nanpy.serialmanager:received:''
Traceback (most recent call last):
  File "lcd.py", line 34, in <module>
    hello()
  File "lcd.py", line 22, in hello
    lcd = Lcd_I2C(pins, [cols, rows], connection=connection)
  File "/usr/local/lib/python2.7/dist-packages/nanpy-0.9-py2.7.egg/nanpy/lcd_i2c.py", line 13, in __init__
    self.id = self.call('new', pins, begin)
  File "/usr/local/lib/python2.7/dist-packages/nanpy-0.9-py2.7.egg/nanpy/arduinoboard.py", line 148, in call
    return _call(self.namespace, self.id, args, self.connection)
  File "/usr/local/lib/python2.7/dist-packages/nanpy-0.9-py2.7.egg/nanpy/arduinoboard.py", line 46, in _call
    ret = return_value(connection)
  File "/usr/local/lib/python2.7/dist-packages/nanpy-0.9-py2.7.egg/nanpy/arduinoboard.py", line 16, in return_value
    return connection.readline().replace('\r\n', '')
  File "/usr/local/lib/python2.7/dist-packages/nanpy-0.9-py2.7.egg/nanpy/serialmanager.py", line 96, in readline
    raise SerialManagerError('Serial timeout!')
nanpy.serialmanager.SerialManagerError: Serial timeout!

User avatar
bitflip
Posts: 1
Joined: Fri May 23, 2014 7:24 am
Location: Lithuania

Re: Using an Arduino as a slave I/O board

Fri May 23, 2014 7:36 am

Just created this account to thank you for this little guide, it really cleared few things out for me, I found some of the nanpy documentation vague. Also, the following piece of code didn't work for me, because I think you made a little mistake, A0 analog pin is not 'pot = 14', but 'pot = 0'. That was my experience, I hope someone finds it useful.
tonygo2 wrote: #!/usr/bin/env python
#Read values from Analogue pin A0
# 10K ohm potentiometer on A0
from nanpy import (ArduinoApi, SerialManager)

connection = SerialManager()
a = ArduinoApi(connection=connection)

from time import sleep

pot = 14 # Pot on A0 - Anaglog input

print"Turn the pot - Analogue input - 10 bit"
for i in range(0,40):
val = a.analogRead(pot) # Analog input
print val
sleep(0.3)

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Sat May 24, 2014 11:27 am

I'm sorry if I was 'a bit vague' but you appear to have got the new version of Nanpy v0.9 to work. I tested the Python code on my system with '14' rather than '0' and it worked on my setup with a genuine Uno R3 board.

Perhaps you would like to help "others who follow" by providing an improved explanation of the bits where I was vague.

Some more examples of working programs would be useful.

Regards

Tony Goodhew

riklaunim
Posts: 269
Joined: Tue Apr 22, 2014 7:34 pm

Re: Using an Arduino as a slave I/O board

Sat May 24, 2014 12:51 pm

You could try other type of "slave" boards, like PyMCU, SerIO, or maybe mbed boards too.

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Tue May 27, 2014 3:12 pm

In my previous code I used pin 'name' 14 rather than A0. The analogue pins A0, A1 ... A5 have aliases 14, 15 ... 19 mainly for use when the analogue pins are being used as digital pins for I/0, if you have run out of digital pins. Both names work equally well with Nanpy.

I hope this clears up any misunderstanding.

Regards

Tony Goodhew

ShaunVW
Posts: 37
Joined: Tue Aug 28, 2012 5:11 pm

Re: Using an Arduino as a slave I/O board

Tue Jun 03, 2014 5:36 am

I have been in contact with Tony & Andrea (writers of Nanpy), trying to sort out why I cannot get my i2c LCD to work with the latest Nanpy v0.9 library.
Andrea thinks it is because of a library that hasn't been included when uploading the firmware to the Arduino.
This is Andrea's reply to me (by email):
I encountered the same error using DallasTemperature module :) I forgot to put into libraries/ the DallasTemperature library before uploading the firmware. In your case I think you forgot to include I2C library before uploading the firmware. You can find the library here: https://bitbucket.org/fmalpartida/new-liquidcrystal

Let me know if this fixes your problem and thanks for using Nanpy :)
Now based on Tony's instructions above that I followed to install Nanpy and upload the firmware to the Arduino, how do I go about "fixing" my installation? I'm not sure if I must fix my firmware upload, or the libraries on the Raspberry itself. (See the link in the reply from Andrea). From Andrea's reply, I think I have to re-upload the firmware to the Arduino. I have the PCF8574 I2C expander on my LCD, so I also need (I'm guessing) to incorporate this driver library into my fix as well?

Please note that I am not strong on Linux, so if anyone can help, bear this in mind.

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Sat Aug 23, 2014 3:32 pm

There is a new way to connect your Pi to an Arduino and use FUZE BASIC rather than Python to drive it.
http://www.raspberrypi.org/forums/viewt ... 3&p=598854

FUZE.co.uk has all the details and a link to download the software as a SD card image.
I'm using the same physical setup as used with NANPY.

User avatar
Onira
Posts: 237
Joined: Tue Oct 02, 2012 6:24 pm
Location: Poland

Re: Using an Arduino as a slave I/O board

Sat Jan 31, 2015 4:58 pm

I get an error in Arduino IDE:

Code: Select all

LiquidCrystalClass.cpp:1.17:fatal error: cfg.h: No such file or directory
compilation terminated.
Cogito ergo sum

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Sun Feb 01, 2015 1:01 pm

Rather a short post. I will need more info to sort out the problem.
Please let me know which version of Nanpy you are using and if you can get an LED to blink at different rates when driven by your Pi.

User avatar
Onira
Posts: 237
Joined: Tue Oct 02, 2012 6:24 pm
Location: Poland

Re: Using an Arduino as a slave I/O board

Sun Feb 01, 2015 6:13 pm

am trying to insert nanpy-0.9 code into the Arduino and when opening /home/pi/nanpy-firmware/nanpy/nanpy.ino I click to verify or upload then it compiles and that error ocurs...
Cogito ergo sum

User avatar
Onira
Posts: 237
Joined: Tue Oct 02, 2012 6:24 pm
Location: Poland

Re: Using an Arduino as a slave I/O board

Fri Feb 06, 2015 8:39 pm

any help? :(
Cogito ergo sum

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Sat Feb 07, 2015 9:20 am

I'm away from home at the moment and cannot access my hobby kit. Every time the writer of Nanpy does an upgrade he makes a significant change to the way it has to be loaded but supplies little documentation for a novice user. You can contact him, Andrea Stagi <stagi.andrea@gmail.com>, here; but if your message goes to spam you will not get a reply!
When I get back I'll see if I can sort something out.
Regards

Tony

richrarobi
Posts: 271
Joined: Sun Feb 08, 2015 1:13 pm

Re: Using an Arduino as a slave I/O board

Sun Feb 08, 2015 4:11 pm

This is probably really a Firmata/Arduino issue rather than a pi issue!!
My second pi has an arduino uno attached for connecting to things. I didn't want to attach 'things' directly to my pi, thought it would be more understandable via arduino.
I used a serial connection instead of usb just by changing the serial address (didn't want to power arduino from pi via usb) see code.
I liked the look of Nanpy but found so little documentation, I have gone back to firmata, loading standard firmata on the uno. So far I have a flashing LED :shock: and a small servo wiggling :lol: - driven simply from python on the pi.

Code: Select all

 import sys, traceback
from time import sleep
from  pyfirmata import Arduino, util

board = Arduino('/dev/ttyAMA0')
pin9 = board.get_pin('d:9:s')
def move_servo(a):
    pin9.write(a)

while True:
   try:
      print 'going high'
      board.digital[2].write(1)
      move_servo(180)
      sleep(1)

      print 'going mid'
#      board.digital[2].write(1)
      move_servo(90)
      sleep(1)

      print 'going low'
      board.digital[2].write(0)
      move_servo(0)
      sleep(1)

   except KeyboardInterrupt:
       board.digital[2].write(0)
       move_servo(0)
       print
       print "program stopped"
       sys.exit(0)
 
I have now hit the documentation problem again as I want to add some instrumentation using i2c - it is probably simple! It looks to be supported.

Does anyone know of a standard firmata guide that details how to use the library, especially the i2c pins?

asandford
Posts: 1998
Joined: Mon Dec 31, 2012 12:54 pm
Location: Waterlooville

Re: Using an Arduino as a slave I/O board

Sun Feb 08, 2015 9:26 pm

richrarobi wrote: Does anyone know of a standard firmata guide that details how to use the library, especially the i2c pins?
There is an i2c firmata sketch supplied, but it's quite old:

Code: Select all

/*
 * Firmata is a generic protocol for communicating with microcontrollers
 * from software on a host computer. It is intended to work with
 * any host computer software package.
 *
 * To download a host software package, please clink on the following link
 * to open the download page in your default browser.
 *
 * http://firmata.org/wiki/Download
 */

/*
 Copyright (C) 2009 Jeff Hoefs.  All rights reserved.
 Copyright (C) 2009 Shigeru Kobayashi.  All rights reserved.
 
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.
 
 See file LICENSE.txt for further informations on licensing terms.
 */

#include <Wire.h>
#include <Firmata.h>


#define I2C_WRITE B00000000
#define I2C_READ B00001000
#define I2C_READ_CONTINUOUSLY B00010000
#define I2C_STOP_READING B00011000
#define I2C_READ_WRITE_MODE_MASK B00011000

#define MAX_QUERIES 8

unsigned long currentMillis;     // store the current value from millis()
unsigned long previousMillis;    // for comparison with currentMillis
unsigned int samplingInterval = 32;  // default sampling interval is 33ms
unsigned int i2cReadDelayTime = 0;  // default delay time between i2c read request and Wire.requestFrom()
unsigned int powerPinsEnabled = 0;  // use as boolean to prevent enablePowerPins from being called more than once

#define MINIMUM_SAMPLING_INTERVAL 10

#define REGISTER_NOT_SPECIFIED -1

struct i2c_device_info {
  byte addr;
  byte reg;
  byte bytes;
};

i2c_device_info query[MAX_QUERIES];

byte i2cRxData[32];
boolean readingContinuously = false;
byte queryIndex = 0;

void readAndReportData(byte address, int theRegister, byte numBytes)
{
  if (theRegister != REGISTER_NOT_SPECIFIED) {
    Wire.beginTransmission(address);
    Wire.write((byte)theRegister);
    Wire.endTransmission();
    delayMicroseconds(i2cReadDelayTime);  // delay is necessary for some devices such as WiiNunchuck
  } 
  else {
    theRegister = 0;  // fill the register with a dummy value
  }

  Wire.requestFrom(address, numBytes);

  // check to be sure correct number of bytes were returned by slave
  if(numBytes == Wire.available()) {
    i2cRxData[0] = address;
    i2cRxData[1] = theRegister;
    for (int i = 0; i < numBytes; i++) {
      i2cRxData[2 + i] = Wire.read();
    }
    // send slave address, register and received bytes
    Firmata.sendSysex(I2C_REPLY, numBytes + 2, i2cRxData);
  }
  else {
    if(numBytes > Wire.available()) {
      Firmata.sendString("I2C Read Error: Too many bytes received");
    } else {
      Firmata.sendString("I2C Read Error: Too few bytes received"); 
    }
  }
  
}

void sysexCallback(byte command, byte argc, byte *argv)
{
  byte mode;
  byte slaveAddress;
  byte slaveRegister;
  byte data;
  int  delayTime;

  if (command == I2C_REQUEST) {
    mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
    slaveAddress = argv[0];

    switch(mode) {
    case I2C_WRITE:
      Wire.beginTransmission(slaveAddress);
      for (byte i = 2; i < argc; i += 2) {
        data = argv[i] + (argv[i + 1] << 7);
        Wire.write(data);
      }
      Wire.endTransmission();
      delayMicroseconds(70); // TODO is this needed?
      break;
    case I2C_READ:
      if (argc == 6) {
        // a slave register is specified
        slaveRegister = argv[2] + (argv[3] << 7);
        data = argv[4] + (argv[5] << 7);  // bytes to read
        readAndReportData(slaveAddress, (int)slaveRegister, data);
      } 
      else {
        // a slave register is NOT specified
        data = argv[2] + (argv[3] << 7);  // bytes to read
        readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);
      }
      break;
    case I2C_READ_CONTINUOUSLY:
      if ((queryIndex + 1) >= MAX_QUERIES) {
        // too many queries, just ignore
        Firmata.sendString("too many queries");
        break;
      }
      query[queryIndex].addr = slaveAddress;
      query[queryIndex].reg = argv[2] + (argv[3] << 7);
      query[queryIndex].bytes = argv[4] + (argv[5] << 7);
      readingContinuously = true;
      queryIndex++;
      break;
    case I2C_STOP_READING:
      readingContinuously = false;
      queryIndex = 0;
      break;
    default:
      break;
    }
  }
  else if (command == SAMPLING_INTERVAL) {
    samplingInterval = argv[0] + (argv[1] << 7);

    if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
      samplingInterval = MINIMUM_SAMPLING_INTERVAL;
    }

    samplingInterval -= 1;
    Firmata.sendString("sampling interval");
  }

  else if (command == I2C_CONFIG) {
    delayTime = (argv[4] + (argv[5] << 7));                        // MSB
    delayTime = (delayTime << 8) + (argv[2] + (argv[3] << 7));     // add LSB

    if((argv[0] + (argv[1] << 7)) > 0) {
      enablePowerPins(PORTC3, PORTC2);
    }

    if(delayTime > 0) {
      i2cReadDelayTime = delayTime;
    }

    if(argc > 6) {
      // If you extend I2C_Config, handle your data here
    }

  }
}

void systemResetCallback()
{
  readingContinuously = false;
  queryIndex = 0;
}

/* reference: BlinkM_funcs.h by Tod E. Kurt, ThingM, http://thingm.com/ */
// Enables Pins A2 and A3 to be used as GND and Power
// so that I2C devices can be plugged directly
// into Arduino header (pins A2 - A5)
static void enablePowerPins(byte pwrpin, byte gndpin)
{
  if(powerPinsEnabled == 0) {
    DDRC |= _BV(pwrpin) | _BV(gndpin);
    PORTC &=~ _BV(gndpin);
    PORTC |=  _BV(pwrpin);
    powerPinsEnabled = 1;
    Firmata.sendString("Power pins enabled");
    delay(100);
  }
}

void setup()
{
  Firmata.setFirmwareVersion(2, 0);

  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.attach(SYSTEM_RESET, systemResetCallback);

  for (int i = 0; i < TOTAL_PINS; ++i) {
    pinMode(i, OUTPUT);
  }

  Firmata.begin(57600);  
  Wire.begin();
}

void loop()
{
  while (Firmata.available()) {
    Firmata.processInput();
  }

  currentMillis = millis();
  if (currentMillis - previousMillis > samplingInterval) {
    previousMillis += samplingInterval;

    for (byte i = 0; i < queryIndex; i++) {
      readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
    }
  }
}

richrarobi
Posts: 271
Joined: Sun Feb 08, 2015 1:13 pm

Re: Using an Arduino as a slave I/O board

Mon Feb 09, 2015 9:15 am

They don't make it clear if the firmata sketch is for running i2c on arduino or for an arduino connected to pi with i2c.
What would python commands look like to drive the i2c on arduino using firmata? I read both the sketch's 20 times and still have no idea what python to write to drive i2c.

My arduino is attached to pi using the gpio serial UART (not USB and especially not i2c).
Much research later, I begin to think that firmata i2c devices are still a twinkle in the programmers eye. Some code is in there but......
Maybe give nanpy another chance, or perhaps give in and put the i2c things direct on the pi. Then I am back to worrying about volts and other colours of smoke.
Using i2c via nanpy also seems to be somewhat xxleading edge. Python example anyone?

tonygo2
Posts: 93
Joined: Sun Aug 28, 2011 2:50 pm
Location: Leicester, UK

Re: Using an Arduino as a slave I/O board

Mon Feb 09, 2015 9:39 am

Why use IIC through an Arduino when you can save those pins and use IIC directly from your Pi? There is plenty of information on the Web all you need do is add SMBus to get it going.

Return to “Interfacing (DSI, CSI, I2C, etc.)”