cancel
Showing results for 
Search instead for 
Did you mean: 

NEO-6M GPS Module Receiving Poor Data

Not_An_Engineer_Sike
Associate II

Hello board. I am attempting to implement an STM32F0 to receive data from a GPS module, a NEO-6M in this case, and then transmit it to an external LoRa module.

 

I am attempting to implement this by initializing a ring buffer and inserting information one character at a time via a UART global interrupt (code below).

To keep the ISR short, I set a flag and disable the ISR at the end of the call to allow the main function to process the data.

I then store the newly stored element in the ring buffer to a different "packet_buffer" in order to allow me to check if the NMEA sentence is correct, which I check for utilizing the minmea library from GitHub. 

 

Here is the issue: Utilizing the current program, I'm--at best--able to get one correct transmission out to an external UART logger (which I'm using to debug the program). In most cases, however, I'm simply getting a "Bad Data" message, which tells me that the data I'm receiving into the buffer isn't high quality, or even passable at that.

The GPS module is getting a lock, so I'm at a bit of a mental-block as to what could be going on software-wise.

Thank you in advance.

 

 

 

 

#include "main.h"
#include "ChangeClockTo48Mhz.h"
#include "string.h"
#include "minmea.h"
#include "Ring_Buffer.h"

#define BUFFERSIZE 120

volatile uint8_t packet_buffer[BUFFERSIZE] = "\0";

volatile int Packet_Flag;
volatile int packet_index;
volatile int Buffer_Flag;
volatile uint8_t temp_hold;


char  *newline;


//Pre-Defined Size of 256 in Header
ring_buffer rbuffer;


void TransmitChar(USART_TypeDef* USARTx, uint8_t ch);
void TransmitString(USART_TypeDef* USARTx, uint8_t * str);

void put_in_buffer(uint8_t entry);
int get_from_que(uint8_t *entry);

void Send_To_LoRa(USART_TypeDef* USARTx);
void SetupRegs(void);

int main(void)
{

  HAL_Init();
  ChangeInternalClockTo48MHZ();
  SetupRegs();


  NVIC_EnableIRQ(USART1_IRQn);

  while (1)
  {

	if(Packet_Flag)
	  {
		temp_hold = rbuffer_get(&rbuffer);
		packet_buffer[packet_index++] = temp_hold;

		if(packet_index >= BUFFERSIZE)
			{
				Buffer_Flag = 1;
				packet_index = 0;
				}



		if(minmea_check(packet_buffer, true))
		{
			Send_To_LoRa(USART1);
			packet_index = 0;
			memset(packet_buffer, 0, strlen(packet_buffer));

		}

		else
		{
			TransmitString(USART1, "Bad Data\n");
			packet_index = 0;
			memset(packet_buffer, 0, strlen(packet_buffer));
		}

			Packet_Flag = 0;
			__enable_irq();

	  }
	}


  }






void USART1_IRQHandler(void)
{
	if(USART1->ISR & (USART_ISR_ORE | USART_ISR_PE))
	{
		USART1->ICR |= USART_ICR_ORECF;
	}

	if ((USART1->ISR & USART_ISR_RXNE))
		{
//		put_in_buffer(USART1->RDR);
		rbuffer_put(&rbuffer, USART1->RDR);
		Packet_Flag = 1;
		__disable_irq();
		}

}




void TransmitChar(USART_TypeDef* USARTx, uint8_t ch){
	while(!(USARTx->ISR & USART_ISR_TXE));
	USART1->TDR = ch;
}


void TransmitString(USART_TypeDef* USARTx, uint8_t* str){
	while(*str != 0)
	{
	TransmitChar(USARTx, *str);
	str++;
	}
}



void Send_To_LoRa(USART_TypeDef* USARTx){

	uint8_t AT_SEND_CMD[125] = "AT+SEND=1,100,";

	//ERROR WITH 2nd Argument String
	strcat(AT_SEND_CMD, packet_buffer);

	TransmitString(USARTx, (uint8_t*) AT_SEND_CMD );
	//TransmitString(USARTx, (uint8_t*) packet_buffer);



}


void SetupRegs(void){


	  RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

	  //Mode Register
	  GPIOA->MODER &= ~(GPIO_MODER_MODER9_0 | GPIO_MODER_MODER10_0);
	  GPIOA->MODER |=  (GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1);

	  //Speed Register
	  GPIOA->OSPEEDR &= (GPIO_OSPEEDR_OSPEEDR9 | GPIO_OSPEEDR_OSPEEDR10);

	  //PUPDR Register (Pulled High)
	  GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR9 | GPIO_PUPDR_PUPDR10);
	  GPIOA->PUPDR |= (GPIO_PUPDR_PUPDR9_0 | GPIO_PUPDR_PUPDR10_0);

	  //Type Register
	  GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_10);

	  //Set the Alternate Functions
	  GPIOA->AFR[1] &= ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2);
	  GPIOA->AFR[1] |= (1 << 4) | (1 << 8);

	  //Enable USART1
	  RCC->APB2ENR |= RCC_APB2ENR_USART1EN;

	  //Baud Rate and Oversampling
	  USART1->BRR = 0x1388;
	  USART1->CR1 &= ~USART_CR1_OVER8;
	  USART1->CR3 &= ~USART_CR3_ONEBIT;

	  //Setting Word Length
	  USART1->CR1 &= ~(USART_CR1_M);

	  //Disable Parity Bit
	  USART1->CR1 &= ~USART_CR1_PCE;

	  //Stop Bit
	  USART1->CR2 &= ~USART_CR2_STOP;


	  //Enable Transmission
	  USART1->CR1 |= USART_CR1_TE;

	  //Enable Receiving Interrupt
	  USART1->CR1 |= USART_CR1_RXNEIE;

	  USART1->CR1 |= USART_CR1_RE;

	  //Enable USART
	  USART1->CR1 |= USART_CR1_UE;


}

 

 

 

Here is the ring buffer header + src files

 

 

/*
 * Ring_Buffer.c
 *
 *  Created on: Sep 2, 2024
 *   
 */
#include "Ring_Buffer.h"
#include <stdint.h>

void rbuffer_initialize(ring_buffer *rbuffer){


	rbuffer->read_index = 0;
	rbuffer->write_index = 0;

}



void rbuffer_put(ring_buffer *rbuffer, uint8_t entry){

rbuffer->buffer[rbuffer->write_index++] = entry;



}


uint8_t rbuffer_get(ring_buffer *rbuffer)
{

return rbuffer->buffer[rbuffer->read_index++];

}
///Ring_Buffer.h



#ifndef RING_BUFFER_H_
#define RING_BUFFER_H_

#include <stdint.h>



typedef struct
{

uint8_t buffer[256];
volatile uint8_t write_index;
volatile uint8_t read_index;



}ring_buffer;


void rbuffer_initialize(ring_buffer *rbuffer);

void rbuffer_put(ring_buffer *rbuffer, uint8_t entry);

uint8_t rbuffer_get(ring_buffer *rbuffer);


#endif /*RING_BUFFER_H_ */

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

There's little value to using 8-bit indexes, it does the modulo 256, but not really efficient at a code level

Problem here looks to be that you don't check or protect the buffer from capacity issues, that the input/output can de-synchronize with the way you flag things.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

4 REPLIES 4

There's little value to using 8-bit indexes, it does the modulo 256, but not really efficient at a code level

Problem here looks to be that you don't check or protect the buffer from capacity issues, that the input/output can de-synchronize with the way you flag things.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

https://github.com/cturvey/RandomNinjaChef/blob/main/f746g_disco_gps.c

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

So I've tried to implement a similar capacity protection element as in the code you sent in your other comment (including getting rid of the circular buffer), but I'm still getting now data.

The only way I'll get to my LoRa send command is if I remove the condition which checks for if the buffer has content.

So then I'm guessing that the data just never actually reaches my buffer somehow?

I've attached my updated ISR and main.

 

int main(void)
{

  HAL_Init();
  ChangeInternalClockTo48MHZ();
  SetupRegs();


  NVIC_EnableIRQ(USART1_IRQn);

  while (1)
  {



		if(Transmission_Flag)
		{

			if(minmea_check(packet_buffer, true))
			{
				Send_To_LoRa(USART1);
				memset(packet_buffer, 0, strlen(packet_buffer));

		        }

			else
			{
				TransmitString(USART1, "Bad Data\n");
				packet_index = 0;
				memset(packet_buffer, 0, strlen(packet_buffer));
			}

			Transmission_Flag = 0;
		}

  }

}
void USART1_IRQHandler(void) //Sync and Queue NMEA Sentences
{

	static char rx_buffer[BUFFERSIZE];
	static int rx_index = 0;


	if(USART1->ISR & (USART_ISR_ORE | USART_ISR_PE)) //Overrun Error
	{
		USART1->ICR |= USART_ICR_ORECF;
	}


	if ((USART1->ISR & USART_ISR_RXNE)) //Received Character?
		{
		char rx = (char)(USART1->RDR & 0xFF);

		if ((rx =='\r') || (rx =='\n')) //CRF character?
		{
			if(rx_index != 0)
			{
				memcpy((void *)packet_buffer, rx_buffer, rx_index); //Copy to static line buffer from dynamic receive buffer
				packet_buffer[rx_index] = 0;
				Transmission_Flag = 1;
			}
		}
		else
		{
			if((rx == '$') || (rx_index == BUFFERSIZE)) //If Resync or Overflow Occurs, Pull Back to Start
			{
				rx_index = 0;
			}
			rx_buffer[rx_index] = rx;
		}
		}

}

 

Never mind last comment. Simply forgot to increment rx_buffer index. Original answer is correct.