Message Boards Message Boards

A shameless plug - interacting with the RPi-GPIO via Mathematica

I spent Thanksgiving weekend playing with Mathematica on my Raspberry Pi.  There's some examples in this forum on writing to the GPIO interface and I wanted to explore reading pins.  I couldn't get the same read/write rates as others have, but I did get a proof-of-concept interface using Manipulate to control an LED turning on/off and watching the response of a photoresistor pointed at the LED.  Details are in my latest blog post and below is the end result



pinHi and pinLo in the Manipulate used to create the output are calls to c-functions that I wrote, integrating MathLink.  LightMeasure[] is simply a wrapper to read the photoresistor response and is based on the analogous python code.
POSTED BY: BoB LeSuer
2 Replies
Very cool! Thanks for sharing!

You should be able to get a little bit better switching performance by using BinaryWrite directly (using 49 for "1" and 48 for "0").
I get about 3.7kHz:

 pi@raspberry-wri2 ~ $ sudo wolfram
 Wolfram Language (Raspberry Pi Pilot Release)
 Copyright 1988-2013 Wolfram Research
 Information & help: wolfram.com/raspi
 
 In[1]:= stream = OpenWrite["/sys/class/gpio/gpio4/value", BinaryFormat-> True];
 
 In[2]:= Do[ BinaryWrite[stream,49]; BinaryWrite[stream,48], {1000} ] // AbsoluteTiming // First
 
Out[2]= 0.276416

In[3]:= 1000/%

Out[3]= 3617.7

In[4]:= Do[ BinaryWrite[stream,49]; BinaryWrite[stream,48], {1000} ] // AbsoluteTiming // First

Out[4]= 0.269015

In[5]:= 1000/%

Out[5]= 3717.3
POSTED BY: Arnoud Buzing
When using MathLink installable programs based on WiringPi, it is possible to really crank up the cycles.   Here's the c code:
 #include <wiringPi.h>
 #include "mathlink.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 
 int pinread(int pin);
 int pinhi(int pin);
 int pinlo(int pin);
int pincycle(int pin, int num);
void multiread(int pin, int num);

int main(int argc, char *argv[]){
  wiringPiSetupGpio();
  return MLMain(argc, argv);
}

int pinread(int pin) {
  pinMode(pin, INPUT);
  return digitalRead(pin);
}


int pinhi(int pin) {
  pinMode(pin, OUTPUT);
  digitalWrite(pin,1);
  return 0;
}

int pinlo(int pin) {
  pinMode(pin, OUTPUT);
  digitalWrite(pin,0);
  return 0;
}

int pincycle(int pin, int num) {
  int i;
  for (i=0;i<num;i++) {
    pinhi(pin);
    pinlo(pin);
  }
  return 0;
}

void multiread(int pin, int num) {
  int i;
  int val[num];
  pinMode(pin, INPUT);
  for (i=0;i<num;i++) {
    val[i]=digitalRead(pin);
  }
  MLPutInteger32List(stdlink, val, num);
  return ;
}
     

And I get results fairly close to what has been reported in other speed tests:
10^6/(pinCycle[24,10^6]//AbsoluteTiming//First)
(* 1.41x10^6 *)
out = multiRead[23,10^6]//AbsoluteTiming;
10^6/out[[1]]
(* 3.29x10^6 *)
POSTED BY: BoB LeSuer
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract