IMPORTANTE: Opção NÃO OFICIAL da WISOL, indicamos uso do KEIL C
O objetivo deste BLOG é demonstrar como é possível programar o módulo WISOL LOM204A02 via Arduino Framework e assim utilizá-lo como OPENCPU (atualmente programado com o KEIL C).
IMPORTANTE: Opção NÃO OFICIAL da WISOL, indicamos uso do KEIL C
O exemplo fará a leitura do sensor AHT10 VIA I2C e então fará a publicação no servidor loraWAN TTN. No exemplo, foi utilizado o KIT LOM204A02 da Wisol, e como gateway LoraWAN um Dragino modelo LG308 e servidor TTN.
I2C
I²C (Inter-Integrated Circuit) é um barramento serial Barramento multimestre desenvolvido pela Philips que é usado para conectar periféricos de baixa velocidade a uma placa mãe, a um sistema embarcado ou a um telefone celular. O nome significa Circuito Inter-integrado e é pronunciado I-ao quadrado-C, ou I-dois-C. Desde o dia 1 de Outubro de 2006, nenhuma taxa de licenciamento é exigida para implementar o protocolo I²C, contudo, algumas taxas ainda são exigidas para obtenção de endereços escravos I²C.
AHT10
O Sensor AHT10 é um componente de alta precisão desenvolvido especialmente para integração em projetos com microcontroladores, Arduino e Raspberry Pi, por exemplo, vindo a fazer a medição precisa da temperatura e umidade.Como principal diferencial, apresenta alta confiabilidade nos resultados, com ótima estabilidade ao longo prazo, além de já ser calibrado de fábrica, proporcionando respostas rápidas, além de possuir forte capacidade anti-interferência.O Sensor AHT10 apresenta comunicação do tipo I2C e dimensões físicas muito pequenas, contando com baixo consumo de energia e pinagem própria para uso imediata, já que está integrado em uma placa.Ele se apresenta como uma ótima opção para substituição de sensores amplamente conhecidos, como o DHT11, AM2302, SHT20, entre outros. Contando ainda com função de compensação de temperatura.
TTN
The Thing Network
A Rede de Coisas (TTN) é uma iniciativa iniciada pela sociedade civil holandesa. O objetivo é ter redes LoRaWAN instaladas em todas as cidades do mundo. Ao interconectar essas redes locais, a TTN quer construir uma infra-estrutura mundial para facilitar uma Internet das Coisas (IoT) pública.
A The Things Network (TTN) é o servidor IoT na nuvem utilizado nesse projeto. É um dos servidores gratuitos para LoRaWAN mais utilizados, com mais de 90 mil desenvolvedores, mais de 9 mil gateways de usuários conectados à rede ao redor do mundo e mais de 50 mil aplicações em funcionamento.
A TTN comercializa nós e gateways LoRa e provê treinamento individual e coletivo para empresas e desenvolvedores que desejam utilizar o LoRa. Possui uma comunidade bem ativa nos fóruns, sempre colaborando e ajudando a resolver problemas, além de prover diversos meios de integrar a TTN com a aplicação que se deseja usar. Possui integração nativa com diversas aplicações como: Cayenne, Hypertext Transfer Protocol (HTTP), permitindo ao usuário realizar uplink para um gateway e receber downlink por HTTP, OpenSensors e EVRYTHNG . Caso o usuário queira criar sua própria aplicação, a TTN disponibiliza Application Programming Interface (API) para uso com Message Queuing Telemetry Transport (MQTT) e diversos Software Developer Kits (SDK) para uso com as linguagens Python, Java , Node.Js , NODE-RED e Go
A rede TTN utiliza o protocolo LoRaWAN objetivando uma cobertura em longo alcance para os dispositivos da rede, caracterizando-a assim com uma Wide Area Network (WAN). Devido ao baixo consumo de energia e ao uso da tecnologia LoRa, é chamada de LPWAN (Low Power Wide Area Network). O grande diferencial da TTN é seu estabelecimento como uma rede aberta (open-source) e colaborativa (crowd-sourced), onde qualquer usuário pode contribuir instalando um gateway em sua residência.
Os elementos da TTN são classificados como:
• Endpoints (nós): Os dispositivos responsáveis pela camada de sensoriamento da rede, o endpoint LoRaWAN. Podem coletar informações através de sensores e também acionar dispositivos/máquinas via atuadores. São configurados através de uma das três classes distintas do protocolo LaRaWAN;
• Gateways: Elementos responsáveis por concentrar e processar as informações enviadas pelos endpoints. Os gateways em geral estão conectados a internet, seja por WiFi/Ethernet ou 3G/4G em locais remotos. Mesmo que uma mesma rede LoRaWAN tenha diferentes objetivos, baseados em aplicações distintas, os gateways possuem o objetivo comum de fornecer a maior área de cobertura possível;
• Aplicações: Conectar e interligar os diferentes dispositivos da rede TTN para o fornecimento de informações gerais sobre a coleta de dados dos dispositivos.
ARDUINO
O que é Arduino? Se você sabe pouco sobre Arduino, por favor dê uma olhada abaixo:
Você conhece Arduino. Instale o IDE primeiro:
https://www.arduino.cc/en/Main/Software
Você conhece Arduino. Instale o IDE primeiro:
https://www.arduino.cc/en/Main/Software
LOM204 e Arduino
LOM204 é baseado em STM32L071. No Arduino STM32 existe este core.
Como instalar Arduino STM32?
adicionar em Arquivo Preferências URLs adicionais
http://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
Em seguida, instale o BSP para STM32. Se a instalação estiver concluída como segue:
LIB LoraWAN para Arduino - LMIC (Catena)
Baixe a biblioteca LoRaWAN de:
mcci-catena/arduino-lmic: LoraWAN-MAC-in-C library, adapted to run under the Arduino environment (github.com)
mcci-catena/arduino-lmic: LoraWAN-MAC-in-C library, adapted to run under the Arduino environment (github.com)
POR FAVOR, LEIA O DOCUMENTO!
Adicione ao Arduino IDE:
Ok, o ambiente de desenvolvimento está pronto. Abra o exemplo TTN-OTA.ino e configure 3 parâmetros para LoRaWAN_OTAA os quais deve ser obtidos no servidor TTN.
Defina mapeamento de Pinos para ser compatível com LOM204.
const lmic_pinmap lmic_pins = {
.nss = RADIO_NSS,
.rxtx = RADIO_ANT_SWITCH_HF,
.rst = RADIO_RESET,
.dio = {RADIO_DIO_0, RADIO_DIO_1, RADIO_DIO_2},
};
Defina a Região
lmic_project_config.h
// project-specific definitions
//#define CFG_eu868 1
//#define CFG_us915 1
#define CFG_au915 1
//#define CFG_as923 1
// #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP /* for as923-JP */
//#define CFG_kr920 1
//#define CFG_in866 1
#define CFG_sx1276_radio 1
//#define LMIC_USE_INTERRUPTS
Adicionar em boards.txt
# LOM204
GenL0.menu.pnum.GENERIC_L072CZYX=WISOL LOM204
GenL0.menu.pnum.GENERIC_L072CZYX.upload.maximum_size=131072
GenL0.menu.pnum.GENERIC_L072CZYX.upload.maximum_data_size=20480
GenL0.menu.pnum.GENERIC_L072CZYX.build.board=GENERIC_L072CZYX
GenL0.menu.pnum.GENERIC_L072CZYX.build.product_line=STM32L072xx
GenL0.menu.pnum.GENERIC_L072CZYX.build.variant=STM32L0xx/LOM204
Teremos então no menu o LOM204
No PACKAGE do STM32, alguns arquivos tiveram que ser alterados:
Em
C:\Users\Usuario\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.2.0\variants\STM32L0xx
Descompacte
Teremos em variants uma placa LOM204
Conteúdo de variant_generic.h (alterado para LOM204)
/*
*******************************************************************************
* Copyright (c) 2020-2021, STMicroelectronics
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/
#pragma once
/*----------------------------------------------------------------------------
* STM32 pins number
*----------------------------------------------------------------------------*/
#define PA0 PIN_A0
#define PA1 PIN_A1
#define PA2 PIN_A2
#define PA3 PIN_A3
#define PA4 PIN_A4
#define PA5 PIN_A5
#define PA6 PIN_A6
#define PA7 PIN_A7
#define PA8 8
#define PA9 9
#define PA10 10
#define PA11 11
#define PA12 12
#define PA13 13
#define PA14 14
#define PA15 15
#define PB0 PIN_A8
#define PB1 PIN_A9
#define PB2 18
#define PB3 19
#define PB4 20
#define PB5 21
#define PB6 22
#define PB7 23
#define PB8 24
#define PB9 25
#define PB10 26
#define PB11 27
#define PB12 28
#define PB13 29
#define PB14 30
#define PB15 31
#define PC0 PIN_A10
#define PC1 PIN_A11
#define PC2 PIN_A12
#define PC13 35
#define PC14 36
#define PC15 37
#define PH0 38
#define PH1 39
// Alternate pins number
#define PA2_ALT1 (PA2 | ALT1)
#define PA3_ALT1 (PA3 | ALT1)
#define PA6_ALT1 (PA6 | ALT1)
#define PA7_ALT1 (PA7 | ALT1)
#define PA14_ALT1 (PA14 | ALT1)
#define PB4_ALT1 (PB4 | ALT1)
#define PB5_ALT1 (PB5 | ALT1)
#define NUM_DIGITAL_PINS 40
#define NUM_ANALOG_INPUTS 13
// On-board LED pin number
#ifndef LED_BUILTIN
#define LED_BUILTIN PNUM_NOT_DEFINED
#endif
// On-board user button
#ifndef USER_BTN
#define USER_BTN PNUM_NOT_DEFINED
#endif
// SPI definitions
#ifndef PIN_SPI_SS
//LOM204
#define PIN_SPI_SS PA4
#endif
#ifndef PIN_SPI_SS1
#define PIN_SPI_SS1 PA15
#endif
#ifndef PIN_SPI_SS2
#define PIN_SPI_SS2 PNUM_NOT_DEFINED
#endif
#ifndef PIN_SPI_SS3
#define PIN_SPI_SS3 PNUM_NOT_DEFINED
#endif
#ifndef PIN_SPI_MOSI
//LOM204
#define PIN_SPI_MOSI PA7
#endif
#ifndef PIN_SPI_MISO
//LOM204
#define PIN_SPI_MISO PA6
#endif
#ifndef PIN_SPI_SCK
//LOM204
#define PIN_SPI_SCK PA5
#endif
#ifndef PIN_SPI3_MOSI
//LOM204
#define PIN_SPI3_MOSI PB15
#endif
#ifndef PIN_SPI3_MISO
//LOM204
#define PIN_SPI3_MISO PB14
#endif
#ifndef PIN_SPI3_SCK
//LOM204
#define PIN_SPI3_SCK PB13
#endif
// I2C definitions
#ifndef PIN_WIRE_SDA
//LOM204
#define PIN_WIRE_SDA PB9
#endif
#ifndef PIN_WIRE_SCL
//LOM204
#define PIN_WIRE_SCL PB8
#endif
// Timer Definitions
// Use TIM6/TIM7 when possible as servo and tone don't need GPIO output pin
#ifndef TIMER_TONE
#define TIMER_TONE TIM6
#endif
#ifndef TIMER_SERVO
#define TIMER_SERVO TIM7
#endif
// UART Definitions
#ifndef SERIAL_UART_INSTANCE
#define SERIAL_UART_INSTANCE 4
#endif
// Default pin used for generic 'Serial' instance
// Mandatory for Firmata
#ifndef PIN_SERIAL_RX
//LOM204
#define PIN_SERIAL_RX PA10
#endif
#ifndef PIN_SERIAL_TX
//LOM204
#define PIN_SERIAL_TX PA9
#endif
//Serial1
#define PIN_SERIAL1_TX PB3
#define PIN_SERIAL1_RX PB4
//Extra LOM204
#define RADIO_TCXO_VCC_PIN PB1
#define RADIO_ANT_SWITCH_PIN_RX PA15
//LMIC
#define RADIO_NSS PA4
#define RADIO_ANT_SWITCH_HF PA15
#define RADIO_RESET PA8
#define RADIO_DIO_0 PA12
#define RADIO_DIO_1 PB2
#define RADIO_DIO_2 PB5
// Extra HAL modules
#if !defined(HAL_DAC_MODULE_DISABLED)
#define HAL_DAC_MODULE_ENABLED
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#ifdef __cplusplus
// These serial port names are intended to allow libraries and architecture-neutral
// sketches to automatically default to the correct port name for a particular type
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
//
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
//
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
//
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
//
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
//
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default.
#ifndef SERIAL_PORT_MONITOR
#define SERIAL_PORT_MONITOR Serial
#endif
#ifndef SERIAL_PORT_HARDWARE
#define SERIAL_PORT_HARDWARE Serial
#endif
#endif
Neste exemplo, será transmitido para LoRaWAN (TTN) os dados do sensor AHT10.
Segue código final (alterado)
/*******************************************************************************
* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
* Copyright (c) 2018 Terry Moore, MCCI
*
* Permission is hereby granted, free of charge, to anyone
* obtaining a copy of this document and accompanying files,
* to do whatever they want with them without any restriction,
* including, but not limited to, copying, modification and redistribution.
* NO WARRANTY OF ANY KIND IS PROVIDED.
*
* This example sends a valid LoRaWAN packet with payload "Hello,
* world!", using frequency and encryption settings matching those of
* the The Things Network.
*
* This uses OTAA (Over-the-air activation), where where a DevEUI and
* application key is configured, which are used in an over-the-air
* activation procedure where a DevAddr and session keys are
* assigned/generated for use with all further communication.
*
* Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in
* g1, 0.1% in g2), but not the TTN fair usage policy (which is probably
* violated by this sketch when left running for longer)!
* To use this sketch, first register your application and device with
* the things network, to set or generate an AppEUI, DevEUI and AppKey.
* Multiple devices can use the same AppEUI, but each device has its own
* DevEUI and AppKey.
*
* Do not forget to define the radio type correctly in
* arduino-lmic/project_config/lmic_project_config.h or from your BOARDS.txt.
*
*******************************************************************************/
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
HardwareSerial Serial1(PB4, PB3);
#include <AHT10.h>
#include <Wire.h>
uint8_t readStatus = 0;
AHT10 myAHT20(AHT10_ADDRESS_0X38, AHT20_SENSOR);
//
// For normal use, we require that you edit the sketch to replace FILLMEIN
// with values assigned by the TTN console. However, for regression tests,
// we want to be able to compile these scripts. The regression tests define
// COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non-
// working but innocuous value.
//
#ifdef COMPILE_REGRESSION_TEST
# define FILLMEIN 0
#else
# warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!"
# define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN)
#endif
// This EUI must be in little-endian format, so least-significant-byte
// first. When copying an EUI from ttnctl output, this means to reverse
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
// 0x70.
static const u1_t PROGMEM APPEUI[8]={ 0xXX, 0xC0, 0x01, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
// This should also be in little endian format, see above.
static const u1_t PROGMEM DEVEUI[8]={ 0x92, 0xXX, 0xEE, 0xFE, 0xFF, 0x1D, 0x57, 0x88 };
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
// This key should be in big endian format (or, since it is not really a
// number but a block of memory, endianness does not really apply). In
// practice, a key taken from ttnctl can be copied as-is.
static const u1_t PROGMEM APPKEY[16] = { 0x55, 0x1E, 0x2D, 0xXX, 0x16, 0x7B, 0x2F, 0xBD, 0x68, 0x5D, 0xE2, 0xE9, 0x9A, 0x40, 0x27, 0x42 };
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}
uint8_t mydata[] = {0,0,0}; //Temperature, Humidity, NULL
static osjob_t sendjob;
// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 15;
// Pin mapping
const lmic_pinmap lmic_pins = {
.nss = RADIO_NSS,
.rxtx = RADIO_ANT_SWITCH_HF,
.rst = RADIO_RESET,
.dio = {RADIO_DIO_0, RADIO_DIO_1, RADIO_DIO_2},
};
void printHex2(unsigned v) {
v &= 0xff;
if (v < 16)
Serial.print('0');
Serial.print(v, HEX);
}
void onEvent (ev_t ev) {
Serial.print(os_getTime());
Serial.print(": ");
switch(ev) {
case EV_SCAN_TIMEOUT:
Serial.println(F("EV_SCAN_TIMEOUT"));
break;
case EV_BEACON_FOUND:
Serial.println(F("EV_BEACON_FOUND"));
break;
case EV_BEACON_MISSED:
Serial.println(F("EV_BEACON_MISSED"));
break;
case EV_BEACON_TRACKED:
Serial.println(F("EV_BEACON_TRACKED"));
break;
case EV_JOINING:
Serial.println(F("EV_JOINING"));
break;
case EV_JOINED:
Serial.println(F("EV_JOINED"));
{
u4_t netid = 0;
devaddr_t devaddr = 0;
u1_t nwkKey[16];
u1_t artKey[16];
LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
Serial.print("netid: ");
Serial.println(netid, DEC);
Serial.print("devaddr: ");
Serial.println(devaddr, HEX);
Serial.print("AppSKey: ");
for (size_t i=0; i<sizeof(artKey); ++i) {
if (i != 0)
Serial.print("-");
printHex2(artKey[i]);
}
Serial.println("");
Serial.print("NwkSKey: ");
for (size_t i=0; i<sizeof(nwkKey); ++i) {
if (i != 0)
Serial.print("-");
printHex2(nwkKey[i]);
}
Serial.println();
}
// Disable link check validation (automatically enabled
// during join, but because slow data rates change max TX
// size, we don't use it in this example.
LMIC_setLinkCheckMode(0);
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_RFU1:
|| Serial.println(F("EV_RFU1"));
|| break;
*/
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if (LMIC.dataLen) {
Serial.print(F("Received "));
Serial.print(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_SCAN_FOUND:
|| Serial.println(F("EV_SCAN_FOUND"));
|| break;
*/
case EV_TXSTART:
Serial.println(F("EV_TXSTART"));
char mydata_temperature_humidity[64];
sprintf(mydata_temperature_humidity, "Temperature: %u Humidity %u",(uint8_t) myAHT20.readTemperature(),(uint8_t) myAHT20.readHumidity());
Serial.println(mydata_temperature_humidity);
mydata[0]=(uint8_t) myAHT20.readTemperature(); //payload
mydata[1]=(uint8_t) myAHT20.readHumidity(); //payload
break;
case EV_TXCANCELED:
Serial.println(F("EV_TXCANCELED"));
break;
case EV_RXSTART:
/* do not print anything -- it wrecks timing */
break;
case EV_JOIN_TXCOMPLETE:
Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept"));
break;
default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned) ev);
break;
}
}
void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
} else {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata)-1, true); //ack
Serial.println(F("Packet queued"));
}
// Next TX is scheduled after TX_COMPLETE event.
}
void setup() {
//LOM204
pinMode(RADIO_TCXO_VCC_PIN,OUTPUT);
digitalWrite(RADIO_TCXO_VCC_PIN,HIGH);
//LOM204
Serial.begin(9600);
Serial.println(F("Starting"));
while (myAHT20.begin() != true)
{
Serial.println(F("AHT20 not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free
delay(5000);
}
Serial.println(F("AHT20 OK"));
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
LMIC_selectSubBand(1); //TTN - FSB2 start in 0
// Start job (sending automatically starts OTAA too)
do_send(&sendjob);
}
void loop() {
os_runloop_once();
}
Gateway
Montagem
Compilando
Gravador
Instale o STM32 Cube Programmer, o Arduino (STM32 PACKAGE) irá reconhecê-lo e então utilizá-lo para programar o LOM204. O Kit LOM204 possui um gravador ST-LINK embarcado.
Caso não tenhas um Kit LOM204 ou seja, apenas um módulo, utilize o um ST-LINK V2
Uma vez gravado o Software, o LOM204 fará o JOIN na LoRaWAN:
Neste exemplo, utilizaremos o LOM204A2 (EVL20XA R1) para requisitar a temperatura e umidade por meio do sensor AHT10 via barramento I2C. O AHT10 deve ser instalado:
UPLINK message
Ligado na UART1
DOWNLINK message
Fontes:
Dúvidas
suporte@smartcore.com.br
Consumo: 8mA no Arduino
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
Nenhum comentário:
Postar um comentário