Skip to main content
Explorer II
September 2, 2024
Solved

NEO-6M GPS Module Receiving Poor Data

  • September 2, 2024
  • 1 reply
  • 1940 views

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_ */

 

 

 

    This topic has been closed for replies.
    Best answer by Tesla DeLorean

    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.

    1 reply

    Graduate II
    September 2, 2024

    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.

    Graduate II
    September 2, 2024