UTILIZANDO LOM204A02 COMO OPENCPU
O objetivo deste BLOG é demonstrar como é possível interagir com o módulo LOM204A02 via API mode ou seja, com acesso aos comandos via API e utilizá-lo como OPENCPU.
Neste exemplo, utilizaremos o LOM204A2 (EVL20XA R1) para requisitar dados do sensor BME280 via barramento I2C.
A programação será via KEIL C, o mesmo utilizado para compilar o firmware dos comandos CLI.
Neste exemplo, será transmitido via LoRa (P2P), pois o objetivo é apenas ler o BME280.
A LIB utilizada foi
BME280
BME280
- O Sensor de Pressão BME280 é um exclusivo modelo capaz de realizar a medição de pressão atmosférica, umidade e temperatura, também conhecido como barômetro é um módulo digital de alta capacidade e resolução, utilizado nas mais diversas aplicações junto a microcontroladores, entre eles, o Arduino.
- Utilizado em projetos de estações meteorológicas e aperfeiçoamento de navegação GPS, ele apresenta grande potencial e mostra ser um produto de grande auxílio para projetistas que procuram um exclusivo produto capaz de executar as três funcionalidades principais sem ocupar muito espaço.
- Através de seu padrão de conexão por I2C, o Sensor de Pressão BME280 aumenta a sua praticidade de utilização, além de contribuir na maior precisão da obtenção de resultados.
- Desenvolvido com base no sensor Bosh ME280, o Sensor possui design simplificado com pequenas dimensõe que tornam este pequeno módulo um produto de fácil adaptação nos mais diversificados projetos, além de contar com 2 exclusivos furos para melhorar a fixação do mesmo junto aos mais diversificados projetos.
CARACTERÍSTICAS:
- Sensor de Pressão BME280;
- Sensor de Umidade;
- Sensor de Temperatura;
- Produto pequeno de fácil utilização;
- Sistema de comunicação I2C;
- Compatível com diversos modelos de microcontroladores;
- Acompanha barra de pinos 180º;
ESPECIFICAÇÕES:
- Modelo:BME280;
- Tensão de operação: 1,8 a 3,6VDC;
- Faixa de Umidade: 0 a 100%;
- Faixa de Temperatura: -40 a 85ºC;
- Faixa de Pressão: 300 a 1100hPa;
- Precisão da umidade: 0,008%;
- Precisão da temperatura: 0,01ºC;
- Precisão da pressão: +/- 1Pa;
- Comunicação: I2C (até 3,4MHz) e SPI (até 10MHz);
- Dimensões (CxLxA): 15,5x11,5x2,5mm;
- Peso: 1,5g.
A ligação foi realizada desta forma
ALGUMAS MUDANÇAS REALIZADAS PARA FUNCIONAR I2C
1) EM stm32l0xx_hal_conf.h, descomentar
#define HAL_I2C_MODULE_ENABLED
2) EM stm32l0xx_hal_msp.h, incluir
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_I2C1;
3) EM main.c configurar pinos SDA e SCL (HAL_I2C_MspInit)
#define MAIN_C_
#include <stddef.h>
#include <string.h>
#include "stm32l0xx_hal.h"
#include <math.h>
#include "board.h"
#include "Utilities.h"
#include "misc.h"
#include "process.h"
#include "timer.h"
#include "init.h"
#include "timer.h"
#include "main.h"
#include "WISOL_API.h"
#include "BMP280.h"
extern uint8_t I2C_Read_Register(uint8_t device_adr, uint8_t internal_adr);
extern void I2C_Write_Register(uint8_t device_adr, uint8_t internal_adr, uint8_t data);
extern I2C_HandleTypeDef hi2c1;
//---------------------------------------------------------------------------------------------------------
// Example
// This example shows how to use the P2P function to send a message or command
// for LIB ver 1.01
//---------------------------------------------------------------------------------------------------------
extern uint8_t ProductState;
extern uint8_t Uart_Rx_buff[272];
char string[200];
/**
* @brief I2C MSP Initialization
* This function configures the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2C1 GPIO Configuration
PB9 ------> I2C1_SDA
PB8 ------> I2C1_SCL
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
/**
* @brief I2C1 Initialization Function
* @param None
* @retval None
*/
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x40011A22;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
//Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
//Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
//Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
uint8_t string_compare(char array1[], char array2[], uint16_t lenght)
{
uint8_t comVAR=0, i;
for(i=0;i<lenght;i++)
{
if(array1[i]==array2[i])
comVAR++;
else comVAR=0;
}
if (comVAR==lenght)
return 1;
else return 0;
}
// reverses a string 'str' of length 'len'
void reverse(char *str, int len)
{
int i=0, j=len-1, temp;
while (i<j)
{
temp = str[i];
str[i] = str[j];
str[j] = temp;
i++; j--;
}
}
// Converts a given integer x to string str[]. d is the number
// of digits required in output. If d is more than the number
// of digits in x, then 0s are added at the beginning.
int intToStr(int x, char str[], int d)
{
int i = 0;
while (x)
{
str[i++] = (x%10) + '0';
x = x/10;
}
// If number of digits required is more, then
// add 0s at the beginning
while (i < d)
str[i++] = '0';
reverse(str, i);
str[i] = '\0';
return i;
}
// Converts a floating point number to string.
void ftoa(float n, char *res, int afterpoint)
{
unsigned char minus_flag = 0;
if(n<0)
{
minus_flag = 1;
n = -n;
}
// Extract integer part
int ipart = (int)n;
// Extract floating part
float fpart = n - (float)ipart;
// convert integer part to string
int i = intToStr(ipart, res, 0);
// check for display option after point
if (afterpoint != 0)
{
res[i] = '.'; // add dot
// Get the value of fraction part upto given no.
// of points after dot. The third parameter is needed
// to handle cases like 233.007
fpart = fpart * pow(10, afterpoint);
intToStr((int)fpart, res + i + 1, afterpoint);
}
char string[30];
if(minus_flag==1)
{
memset(string, 0, 30);
string[0]='-';
if(n<1.0f)
{
string[1]='0';
strcpy(&string[2], res);
}else
strcpy(&string[1], res);
memset(res, 0, strlen(res));
strcpy(res, string);
}else
if(n<1.0f)
{
string[0]='0';
strcpy(&string[1], res);
memset(res, 0, strlen(res));
strcpy(res, string);
}
}
int main(void)
{
Start_Init();
MX_I2C1_Init();
BMP280_init();
BMP280_calc_values();
init_height=altitude;
do
{
BMP280_calc_values();
memset(&string, 0, strlen(string));
strcat(string, "Temperature: ");
ftoa(temperature, &string[strlen(string)], 3);
strcat(string, " C\n");
strcat(string, "Pressure: ");
ftoa(pressure, &string[strlen(string)], 3);
strcat(string, " Pa\n");
strcat(string, "Altitude: ");
ftoa(altitude, &string[strlen(string)], 3);
strcat(string, " m\n");
strcat(string, "Relative altitude: ");
ftoa(altitude-init_height, &string[strlen(string)], 3);
strcat(string, " m\n\n\n");
PRINTF("%s",string);
HAL_Delay(1000);
}while(true);
}
void Start_Init(void)
{
HW_SystemClock_Config();
StartNVInit();
BoardInitPeriph( );
BoardInitMcu( );
Var_Init();
sub_process_init(); // set receive mode for uart
#ifdef DEBUG_GPIO
Timer_1ms_Start(IDLE_MODE_TIME_OUT,200,0xff,BIT0_fn); // When a module enters sleep, it no longer works.
#endif
TimerInit( &TxNext, Txnext_fn ); // Do not modify
/*
#if defined (USE_BAND_920)
#ifndef OLD_CLI_COMPATIBILITY_MODE
TimerInit( &Rest_send, restrict_send);
#endif
#endif
*/
nvm_init(); // To read the configuration saved in EEPROM.
Clr_BIT2();
LDO_on();
}
void Restart_Init(void)
{
BoardInitPeriph( );
BoardInitMcu( );
Var_Init();
sub_process_init(); // set receive mode for uart
#ifdef DEBUG_GPIO
Timer_1ms_Start(IDLE_MODE_TIME_OUT,200,0xff,BIT0_fn); // When a module enters sleep, it no longer works.
#endif
TimerInit( &TxNext, Txnext_fn ); // Do not modify
/*
#if defined (USE_BAND_920)
#ifndef OLD_CLI_COMPATIBILITY_MODE
TimerInit( &Rest_send, restrict_send);
#endif
#endif
*/
nvm_init(); // To read the configuration saved in EEPROM.
Clr_BIT2();
LDO_on();
}
4) Compilando
5) Fazendo o UPLOAD
Projeto
Fontes:
Datasheets
SCH_EVL20xA_R1_170630.pdf
Datasheet_LOM204A_V0.1_20190715.pdf
Dúvidas
suporte@smartcore.com.br
Sobre a SMARTCORE
A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portfólio inclui modem 2G/3G/4G/NB-IoT/Cat.M, satelital, módulos WiFi, Bluetooth, GNSS / GPS, Sigfox, LoRa, leitor de cartão, leitor QR code, mecanismo de impressão, mini-board PC, antena, pigtail, LCD, bateria, repetidor GPS e sensores.
Mais detalhes em www.smartcore.com.br