0

I am trying to read from a gps module NEO-6M using Raspbery Pi 3 B over SPI. It nicely works with Arduino but it doesn't want to work with Raspberry.

I have used different libraries in Pyhon, even JavaScript with Node but still got the same result. On Arduino I use spi mode 0, with CS active low. This is the code I used in Python

import spidev
import time
spi = spidev.SpiDev()
spi.open(0, 0)
spi.cshigh = False
spi.max_speed_hz = 100000 #100kHz as recommended in the datasheet of the gps module
spi.mode = 0
while True:
    res = spi.xfer2([0xFF])
    print(res)
    time.sleep(0.15)

The way I know that the response is garbage is that gps returns NMEA values separated by comma which has 44 in ASCII but I rarely get 44 in the output, moreover it is full of non-printable characters like 0, 255, 1, 5, etc.

Also, I want to add that this code worked only once (after multiple tries, just suddenly) and after rerunning the script it again started to return garbage. What is going on?

EDIT

This is a working code for Arduino:

#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

byte clr;
//data buffer
char buffer [128];
byte output_data;

void fill_buffer()
{
  for (int I=0;I<128;I++)
  {
    buffer[I]=I;
  }
}

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void setup()
{
  Serial.begin(9600);

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR)| (1<<SPR1) | (1<<SPR0);
  clr=SPSR;
  clr=SPDR;
}

byte read()
{
  int data;
  digitalWrite(SLAVESELECT,LOW);
  data = spi_transfer(0x00); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
}

void loop()
{
  output_data = read();
  if ((int)output_data != 255) //sometimes 255 values come in the output
    Serial.print((char)output_data);
  delay(100); //pause for readability
}

Also, just now the python code above worked again. Still can't realized what makes it stop working.

EDIT 2

I just realized in which cases it works! When I power on the gps module with all wires connected, raspberry reads garbage from it. Instead, when I disconnected VCC and MISO wires, connect VCC first and only then MISO then it gets right data. Can someone explain how I can handle this problem and how to properly mount the module to circuit? Because the module is going to be used autonomously without human interaction.

  • you are asking an incorrect question ..... the question should be Why does Arduino work nicely with it but Raspberry does not want to work with it? ...... the problem is the RPi, not the NEO-6M. – jsotola Jul 29 '18 at 17:56
  • I doubt "It nicely works with Arduino" because Arduino doesn't support Python. Have you enabled SPI? This question is too vague. – Milliways Jul 29 '18 at 19:37
  • @Milliways yes, I enabled SPI with raspi-config. It may seem vague because I have tried all combinations that came to my mind and still can't realize which options might be left to try. So, I don't quite know the source of problem (python, rp or neo) to put the question more specifically – Turkhan Badalov Jul 29 '18 at 19:46
  • Following the comment by @Milliways, I assume the Python that you're showing represents your attempt on the Raspberry Pi. Can you also show the code that you used on the Arduino (that you say worked) for comparison? – Brick Jul 30 '18 at 13:23
  • @Brick, added the code. Also, python code worked again for unknown to me reasons. – Turkhan Badalov Jul 31 '18 at 11:37
0

If your GPS module has a reset input, consider resetting it with a GPIO once your RPi has started up, and the VCC voltage has been stable for a while.

If there's no reset or it doesn't help, consider adding 1k..10k resistors in series in all SPI lines. This should prevent the module from receiving power from data lines before the VCC voltage stabilizes, which may cause this kind of problem. Keep in mind that series resistors may become problematic if you later decide to increase the SPI baudrate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.