guerogemichael
Posts: 1
Joined: Sat May 28, 2016 5:04 pm

Gertboard Analog Input

Sat May 28, 2016 5:07 pm

I need help! Is there anybody out there who can tell me how I am able to read the input signal of the gertboard? I am a total noob and on the dragon.net I found this: int gertboardAnalogRead (int channel) but when try it it says undefined! gpio gar 0 in the console works. I just want to get the number between 0 and 1023 into my program as the simplest way! please help me

Code:

// WiringPi-Api einbinden
#include <wiringPi.h>

// C-Standardbibliothek einbinden
#include <stdio.h>
#include <wiringPiSPI.h>
#include <gertboard.h>
#include "gb_spi.h"

#define SPI_ADC_SPEED 1000000
#define SPI_A2D 1

int main() {

int value;

// Starte die WiringPi-Api
if (wiringPiSetup() == -1)
return 1;

int gertboardSPISetup (void)
{
if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0)
return -1 ;

return 0 ;
}

// Schalte GPIO 17 (=WiringPi Pin 0) auf Ausgang
pinMode(6, OUTPUT);


while(value < 500)
{
// LED an
digitalWrite(6, 1);

// Warte 100 ms
delay(100);

// LED aus
digitalWrite(6, 0);

// Warte 100 ms
delay(100);
}

value = gertboardAnalogRead(1);

}


root@raspberrypi:/michi# nano programm.c
root@raspberrypi:/michi# gcc programm.c -o dddd -lwiringPi
/tmp/ccvVs0Sm.o: In function `main':
programm.c:(.text+0x6c): undefined reference to `gertboardAnalogRead'
collect2: error: ld returned 1 exit status

Thank you for you help!

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Gertboard Analog Input

Mon May 30, 2016 5:39 am

Here is the atod.c gertboard A/D demo code from 2013; I have not tested it yet... later tonight... but I thought I'd pass it along so that you can have it to study, or try !

Code: Select all

//
// Gertboard Demo
//
// SPI (ADC/DAC) control code
//
// This code is part of the Gertboard test suite
//
//
// Copyright (C) Gert Jan van Loo & Myra VanInwegen 2012
// No rights reserved
// You may treat this program as if it was in the public domain
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//
// Try to strike a balance between keep code simple for
// novice programmers but still have reasonable quality code
//

#include "gb_common.h"
#include "gb_spi.h"

// Set GPIO pins to the right mode
// DEMO GPIO mapping:
//         Function            Mode
// GPIO0=  unused
// GPIO1=  unused
// GPIO4=  unused
// GPIO7=  unused
// GPIO8=  SPI chip select A   Alt. 0
// GPIO9=  SPI MISO            Alt. 0
// GPIO10= SPI MOSI            Alt. 0
// GPIO11= SPI CLK             Alt. 0
// GPIO14= unused
// GPIO15= unused
// GPIO17= unused
// GPIO18= unused
// GPIO21= unused
// GPIO22= unused
// GPIO23= unused
// GPIO24= unused
// GPIO25= unused
//

// For A to D we only need the SPI bus and SPI chip select A
void setup_gpio()
{
   INP_GPIO(8);  SET_GPIO_ALT(8,0);
   INP_GPIO(9);  SET_GPIO_ALT(9,0);
   INP_GPIO(10); SET_GPIO_ALT(10,0);
   INP_GPIO(11); SET_GPIO_ALT(11,0);
} // setup_gpio


//
//  Read ADC input 0 and show as horizontal bar
//
void main(void)
{ int r, v, s, i, chan;

  do {
    printf ("Which channel do you want to test? Type 0 or 1.\n");
    chan  = (int) getchar();
    (void) getchar(); // eat carriage return
  } while (chan != '0' && chan != '1');
  chan = chan - '0';

  printf ("These are the connections for the analogue to digital test:\n");
  printf ("jumper connecting GP11 to SCLK\n");
  printf ("jumper connecting GP10 to MOSI\n");
  printf ("jumper connecting GP9 to MISO\n");
  printf ("jumper connecting GP8 to CSnA\n");
  printf ("Potentiometer connections:\n");
  printf ("  (call 1 and 3 the ends of the resistor and 2 the wiper)\n");
  printf ("  connect 3 to 3V3\n");
  printf ("  connect 2 to AD%d\n", chan);
  printf ("  connect 1 to GND\n");
  printf ("When ready hit enter.\n");
  (void) getchar();

  // Map the I/O sections
  setup_io();

  // activate SPI bus pins
  setup_gpio();

  // Setup SPI bus
  setup_spi();

  // The value returned by the A to D can jump around quite a bit, so 
  // simply printing out the value isn't very useful. The bar graph
  // is better because this hides the noise in the signal.

  for (r=0; r<100000; r++)
  {
    v= read_adc(chan);
    // V should be in range 0-1023
    // map to 0-63
    s = v >> 4;
    printf("%04d ",v);
    // show horizontal bar
    for (i = 0; i < s; i++)
      putchar('#');
    for (i = 0; i < 64 - s; i++)
      putchar(' ');
    putchar(0x0D); // go to start of the line
    short_wait();
  } // repeated read

  printf("\n");
  restore_io();
} // main


Edit: PS All of the test suite for Gertboard is available on Element14 (including the python versions)
Last edited by MarkHaysHarris777 on Mon May 30, 2016 1:28 pm, edited 2 times in total.
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Gertboard Analog Input

Mon May 30, 2016 6:21 am

Also, you do have the manual, for the Gertboard, yes?

You may find it more useful, and more fun, to program the Atmel Atmega328P AVR on the Gertboard to get your analog readings. The 328P can pass the values back on serial. The downside is that there is some minimal setup that has to be done from Gordon @ drogon (its easy, and he's automated most of it) so that you can use the Arduino IDE to program the AVR ./// if you've ever programmed the Arduino its the same drill... there are six analog inputs and reading them is easy (getting serial to work, on the other hand can be a challenge)

I'm excited to get the A/D D/A chips working on SPI (particularly on python)

keep you posted
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Gertboard Analog Input

Mon May 30, 2016 8:54 am

My test suite for A/D D/A compiled without errors on the 3B; but the atod.c program hangs forever in

read_adc(chan)

The program prompts for the channel, sets up spi, gpio, etc and then starts the read loop() which fails immediately with the hang in read_adc(chan).

I tried both GPIO08 and GPIO07 (recompiles) as the chip select (same issue). I am wondering if the spi driver is interferring with the testsuite. I have /dev/spi* devices 0 and 1.

Well, I'm having no luck with the C testsuite either. rats.
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Gertboard Analog Input

Mon May 30, 2016 9:20 am

:shock:
Last edited by MarkHaysHarris777 on Mon May 30, 2016 1:29 pm, edited 1 time in total.
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Gertboard Analog Input

Mon May 30, 2016 11:17 am

From a python script the easiest way to read the mcp3002 on the Gertboard and pull the value into a reference is to use the subprocess module:

Code: Select all

>>>from subprocess import check_output
>>>value = int(check_output("gpio gbr 1", shell=True))
>>>value
471
>>>value - 71
400
>>>

wiringpi for python has an mcp3002Setup(); alas, I don't know how to use it yet... wiringpi for python is not documented well; almost not at all. :?

We'll get there... geeeze, I'm glad that reading the mcp3002 is trivial ... cause otherwise ... ah never mind.
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Gertboard Analog Input

Mon May 30, 2016 12:22 pm

Ok, here is the wiringpi (for python) method for reading the mcp3002 chip on the Gertboard:

First, get it:

sudo apt-get install python-dev

sudo pip install wiringpi2

So, here is the code snippet in the python REPL:

Code: Select all

sudo python ...
>>>import wiringpi as wpi
>>>wpi.wiringPiSetup()
0
>>>wpi.mcp3002Setup(70, 0)
1
>>>value  =  wpi.analogRead(71)
>>>print(value)
485
>>>

Documentation on GitHub, and http://wiringpi.com (thanks Gordon)

Notes: The issue for me was the pinBase, and the channel... for the new node function
mcp3002Setup(pinBase, Channel)... In the example above I'm reading from ADC channel 1, on SPI channel 0.
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Gertboard Analog Input

Mon May 30, 2016 12:48 pm

So, here's the python script mcp3002.sh which will easily read the mcp3002 chip on the Gertboard with python and wiringpi (for python)...

mcp3002.sh

Code: Select all

#!/usr/bin/python
import wiringpi as wpi
from time import sleep

wpi.wiringPiSetup()
wpi.mcp3002Setup(70, 0)

for n in range(50):
    value = wpi.analogRead(71)
    print(value)
    sleep(1.0)

To test this code I placed a 10K ohm variable resistor across 3v3 (outside pins) and placed the wiper on the mcp3002 ADC channel 1... as the code ran I moved the wiper from extremes which correctly displayed values from 0 - 1023.

Notes: I see why folks are calling these routines trivial... because, for the initiated, they appear very simple indeed (NOT) and only because ALL of the complexity (and its extremely complex) is completely obfuscated... and to make things worse, hidden so thoroughly that no one can find it...

... without searching for a couple of hours. And I feel sorry for the bloke who is still stuck back there trying to get the C samples running... which are so convoluted and painfully complex, they are embarrassing ! :oops:

:shock:

(maybe pulling my chain, ey?)

edit: PS this SPI lecture is interesting. (starts about 9 mins in, about 40 minutes)
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Gertboard Analog Input

Mon May 30, 2016 9:10 pm

edit: PS this SPI lecture is interesting. (starts about 9 mins in, lecture is about 40 minutes)

This link is the mcp3002 datasheet from Microchip. This datasheet is dreadfully complete (30 pages) and fully describes what's going on in our four lines of python code !

These guys in class (unfortunately for them) don't get to use four lines of python... they have to code the bit-banging themselves (based on the datasheet) and using nothing but the raw pins on-off settings (and of course severe timing).

marcus

edit: the lecture is using a different chip, but the concepts are all the same... and some of the difficulties !
marcus
:ugeek:

n2ballroy
Posts: 2
Joined: Sun Jan 01, 2017 11:12 pm

Re: Gertboard Analog Input

Mon Jan 02, 2017 12:00 am

I have a raspberryPi 3 model B with Raspbian Jessie and a gertboard. By the way this was installed with Noobs.

I have successfully tested most of the wiringpi gertboard examples c programs which are included with wiringpi. My problem is erroneous ADC readings anytime the ADC result requires more than 7bits to represent the analog value. This example program voltmeter.c from the wiringpi distro which demonstrates the problem uses SPI to communicate with the gertboard MCP3002 ADC chip.

Problem debug so far:
When I apply a voltage anywhere between 0.0 & 0.410 volts to either AD0 or AD1 the example program voltmeter.c readings are correct. These ADC integer values also correspond to 0x0000 thru 0x007f.
When I apply 0.414 volts the voltmeter.c readings suddenly jump to .826 volts. These ADC integer values suddenly jump to 0x0100 but should be 0x0080. It seems as though the 8th bit is getting shifted to the 9th bit.
This single shifted bit trend continues up to an applied voltage of 1.65 volts which voltmeter.c reads as 2.887v which corresponds to 0x037f.

When I slightly increase the applied voltage to 1.656 volts, then the voltmeter.c readings drop to 0.0V which obviously corresponds to 0x0000.
When I continue raising the voltage then the lower bits increase just as expected.

I appears to me that the SPI transfers using the raspberry PI model C is having some odd problem.

Help, I have spent way too many hours on this.

User avatar
Gert van Loo
Posts: 2440
Joined: Tue Aug 02, 2011 7:27 am
Contact: Website

Re: Gertboard Analog Input

Tue Jan 03, 2017 12:03 pm

I have not looked at that for 4 years.
Your story is very detailed and full of usefull information. As such: Job well done!
Initially I could not think off what might be the cause of your problems.
In the end I had another look at the C-code; specific the SPI read routine.

To my surprise (and shame!) I found this:
(Copied from the driver including all the original typos)

Code: Select all

  // Data from the ADC chip should now be in the receiver
  // read the received data
  v1 = SPI0_FIFO;
  v2 = SPI0_FIFO;
  // Combine the 8-bit and 2 bit values into an 10-bit integer
  // NOT!!!  return ((v1<<8)|v2)&0x3FF;
  // I have checked the result and it returns 3 bits in the MS byte not 2!!
  // So I might have my SPI clock/data pahse wrong.
  // For now its easier to dadpt the results (running out of time)
  return ( (v1<<7) | (v2>>1) ) & 0x3FF;
} // read_adc
In your case have a look what the values of v1 and v2 are.
As you can see (or not) from the above code, I found that all bits where shifted too far left by one position and
the C-code compensates for that.
I would not be surprised at all if this has worked 'wrong' for four years for everbody, but for some magical reason, it works different for you.
Good luck and keep me informed.

ps:It also shows an extreem good example of why it is important to add comment to your code!

User avatar
JohnBeardmore
Posts: 196
Joined: Thu Nov 15, 2012 11:03 pm
Location: Derbyshire UK.
Contact: Website

Re: Gertboard Analog Input

Tue Jan 03, 2017 10:07 pm

:)

No pressure Gert, but out here in naive user land, we tend to think of your code as definitive and correct !

If there is a problem with clock / data phase, would this affect all the Gertboard examples, or just the A to D ? I've been using the Gertboard A to D inputs to read temperature for a few years now. It always worked pretty well through the Atmega (though that had some code on board to do a rolling average). I was always a bit disappointed by the two input A to D though. The LSBs always seemed a bit random. Maybe there was more to it than noise pickup ?

Having used Gertboards for a few projects, I decided to design my own pi support PCB with power supply, watchdog timer, A to Ds and a D to A. See http://t4sustainability.co.uk/oBeMS/Har ... Jb0008.pdf http://t4sustainability.co.uk/oBeMS/oBe ... icRev5.pdf and http://t4sustainability.co.uk/oBeMS/Boa ... Jb0013.pdf - it all seems to work fine except the MCP4802 SPI D to A. I tried testing that using C code based on the Gertboard D to A test program, but it never seemed to work. I don't investigate very enthusiastically as it was only there for future proofing. But as I was trying to test it using code based on the Gertboard D to A C language example, I wonder if there is a clock / data phase issue, if that might be part of my problem.

It would be useful to get to the bottom of this.

Out of interest, where are the latest releases of the Gertboard C language code best downloaded ?

Cheers, and thanks for the examples and inspiration ! J/.
Author of oBeMS open source Building energy Management System.
Automatic Meter Reading (AMR), Building Management System (BMS),
Building Energy Management System (BEMS), Infrastructure Control System (ICS).
See: http://t4sustainability.co.uk/oBeMS/

n2ballroy
Posts: 2
Joined: Sun Jan 01, 2017 11:12 pm

Re: Gertboard Analog Input

Wed Jan 04, 2017 10:21 pm

I found the file in wiringPi which needed the edit. It was wiringPi/devLib/gertboard.c. The function was gertboardAnalogRead. I made something very close to the change you suggested and performed a build. The gertboard ADC works great now. Thank Gert you for finding this solution. I have spent way too many hours working on this.

To address the other post, the problem does not exist when using the ATmega ADCs. It is only when the getting the MCP3002 ADC via SPI directly to the Rpi.

The new code is

Code: Select all

int gertboardAnalogRead (const int chan)
{
  uint8_t spiData [2] ;

  uint8_t chanBits ;

  if (chan == 0)
    chanBits = 0b11010000 ;
  else
    chanBits = 0b11110000 ;

  spiData [0] = chanBits ;
  spiData [1] = 0 ;

  wiringPiSPIDataRW (SPI_A2D, spiData, 2) ;

  return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ;
The old code was

Code: Select all

int gertboardAnalogRead (const int chan)
{
  uint8_t spiData [2] ;

  uint8_t chanBits ;

  if (chan == 0)
    chanBits = 0b11010000 ;
  else
    chanBits = 0b11110000 ;

  spiData [0] = chanBits ;
  spiData [1] = 0 ;

  wiringPiSPIDataRW (SPI_A2D, spiData, 2) ;

  return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ;
After making the code edit run
$ cd ~/wiringPi
$ ./build

Return to “Gertboard classic”

Who is online

Users browsing this forum: No registered users and 1 guest