I have 2 LoRa modules. I want to use one of them as receiver and the other one as transmitter. I can do this with 2 Arduino Unos, but I want to use one STM32 board as transmitter and Arduino Uno board as receiver. I am using an Ebyte LoRa module, E32433T20D.
I set the receiver like this :
{0x00, 0x01, 0x1A, 0x17, 0xC0} ;
Here is my Arduino transmitter code.
#define PIN_SERIAL1_TX (0u)
#define PIN_SERIAL1_RX (1u)
#define M0 14
#define M1 15
void setup() {
pinMode(M0, OUTPUT);
pinMode(M1, OUTPUT);
digitalWrite(M0, LOW);
digitalWrite(M1, LOW);
Serial1.begin(9600); // UART initialize I am using RP2040 with Arduino code
}
void loop() {
Serial1.write((byte)0x00); // Receiver address
Serial1.write(0x01); // Receiver address
Serial1.write(0x17); // Receiver channel = 0x17 = 23 (410M+23=433 MHz)
Serial1.println("123");
delay(500);
}
This code can transmit "123" without any problem. When I try this in C:
#include "main.h"
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void); //debug
static void MX_USART1_UART_Init(void); //Lora
/* USER CODE BEGIN 0 */
uint16_t readValue;
uint8_t charToTransmit[1];
/* USER CODE END 0 */
int main(void) {
HAL_Init();
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init(); //DEBUG
MX_USART1_UART_Init();
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,0); //M0
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,0); //M1
HAL_Delay(100);
uint8_t config[]= {0x00,0x01,0x1A,0X17,0XC0};
/* USER CODE BEGIN WHILE */
while (1) {
charToTransmit[0] = 1 ;
HAL_UART_Transmit(&huart1,config,sizeof(config),0);
HAL_Delay(500);
HAL_UART_Transmit(&huart1,charToTransmit,1,100);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
// There is HAL library initialization over here
This code is not transmitting or my receiver is not receiving, I don't know, but I can't see "1" on my receiver. Since I am a beginner in C, is my UART protocol wrong or something?
Here is my receiver program, I wrote it in the Arduino IDE too.
#include <Arduino.h>
#define PIN_SERIAL1_TX (0u)
#define PIN_SERIAL1_RX (1u)
#define M0 14
#define M1 15
char rc;
void setup() {
Serial.begin(115200);
Serial1.begin(9600);
pinMode(M0, OUTPUT);
pinMode(M1, OUTPUT);
digitalWrite(M0, LOW);
digitalWrite(M1, LOW);
}
void loop() {
while (Serial1.available()) {
rc=Serial1.read();
Serial.print(rc);
}
}
Related
Hello Im trying to connect a ESP8266 to a STM32 via UART.
I want to use the STM32 to send AT commands to the ESP, so that the ESP can do HTTP GET requests.
The code down here works when I use my PC to send data via FTDI to the STM, then the interrupt is called everytime a byte is recieved.
But when i hook up the ESP8266 I don't get a response even thought im sending AT\r\n;
Also i just connected everything like so:
SMT32 Tx -- ESP Rx
ESP Tx -- FTDI Rx
And I sended the AT\r\n command from the SMT to the ESP and on my pc in putty I got the OK command back, so the ESP is responding. But the interrupt is not called.
#include "main.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
char Rx_Byte[1]; // Creating a single byte buffer
uint8_t Rx_Buffer[256]; // Full buffer
uint8_t Rx_Buffer_Index = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
HAL_UART_Receive_IT(&huart1, (uint8_t *)Rx_Byte, 1);
memcpy(Rx_Buffer + Rx_Buffer_Index, Rx_Byte, 1);
Rx_Buffer_Index++;
if (*Rx_Byte == '\r' || *Rx_Byte == '\n') {
// I could send data via putty and FTDI, and when enter was pressed it printed the data in the buffer back to you via uart
// HAL_UART_Transmit(&huart1, (uint8_t *) Rx_Buffer, Rx_Buffer_Index, 1000);
memset(Rx_Buffer, 0, sizeof(Rx_Buffer)); // Clear buffer
Rx_Buffer_Index = 0;
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_USB_DEVICE_Init();
char echo_off[] = "ATE0\r\n";
char data[] = "AT\r\n";
HAL_Delay(1000);
HAL_UART_Transmit(&huart1, (uint8_t*)echo_off, sizeof(echo_off), 10);
while (1)
{
HAL_GPIO_TogglePin(GPIOA, LED_1_Pin);
HAL_UART_Transmit(&huart1, (uint8_t*)data, sizeof(data), 1000);
HAL_Delay(500);
}
}
I have an Adafruit Feather ATMega 32u4. I want to put it into sleep mode and wake it up with pressing a switch as an external interrupt. This is what I tried so far and which worked:
switching a LED on and off with the switch
putting the Adafruit to sleep and let it wake up with a watchdog timer.
I tried to combine the code examples that I found in the Internet to make the code fit my board. I manage to put it to sleep but then I have to reset it because the Interrupt doesn't work. I would be very happy for any help and please don't blame me, I am a complete beginner!
Here is my code:
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
int pin2 = 2;
void pin2Interrupt(void) {
/* This will bring us back from sleep. */
detachInterrupt(digitalPinToInterrupt(2));
}
void enterSleep(void) {
/* Setup pin2 as an interrupt and attach handler. */
delay(100);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
attachInterrupt(digitalPinToInterrupt(2), pin2Interrupt, RISING);
if (digitalRead(pin2)){
sleep_mode();
}
/* The program will continue from here
* First thing to do is disable sleep.
*/
sleep_disable();
}
void setup() {
Serial.begin(9600);
/* Setup the pin direction. */
pinMode(pin2, INPUT_PULLUP);
Serial.println("Initialisation complete.");
}
int seconds = 0;
void loop() {
delay(1000);
seconds++;
Serial.print("Awake for ");
Serial.print(seconds, DEC);
Serial.println(" second");
if(seconds == 3){
Serial.println("Entering sleep");
delay(200);
seconds = 0;
enterSleep();
}
}
Update:
#include "LowPower.h"
#include "avr/interrupt.h"
#define BUTTON 3
#define LEDPIN 13
void wakeUp() {
detachInterrupt(digitalPinToInterrupt(BUTTON));
}
void Blink(byte ledPin, int msDelay, byte loops) {
for (byte i=0; i<loops; i++) {
digitalWrite(ledPin, LOW);
delay(msDelay);
digitalWrite(ledPin, LOW);
delay(msDelay);
}
}
void setup() {
pinMode(BUTTON, INPUT);
digitalWrite(BUTTON, LOW);
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, LOW);
}
void loop() {
cli();
EIMSK &= ~(1 << INT0);
EICRA |= (1 << ISC01) | (1 << ISC00);
EIMSK |= (1 << INT0);
attachInterrupt(digitalPinToInterrupt(BUTTON), wakeUp, CHANGE);
sei();
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
Blink(LEDPIN, 100, 3);
Serial.println("AWAKE!");
delay(100);
}
I am doing an autonomous car project, I need manual control as well as an autonomous function, so the manual control is done through wifi using "gesture control" and for the autonomous control I want to send the location data via an HTTP request, but then I have to switch to an STA mode, so I want to use a Toggle switch connected to ground and a pin as input and put it in an "if statement", but all of the initial setups come in the void setup(), so I don't know how to proceed I have provided the AP part of the main code I am using
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include <TinyGPS++.h> // Tiny GPS Plus Library
#define CHANNEL 4
uint8_t mac[] = {0x36, 0x33, 0x33, 0x33, 0x33, 0x33};
struct __attribute__((packed)) DataStruct {
//char text[32];
int x;
int y;
unsigned long time;
};
DataStruct myData;
//**********************************************
// GPS Locations
unsigned long Distance_To_Home; // variable for storing the distance to destination
int ac =0; // GPS array counter
int wpCount = 0; // GPS waypoint counter
double Home_LATarray[50]; // variable for storing the destination Latitude - Only Programmed for 5 waypoint
double Home_LONarray[50]; // variable for storing the destination Longitude - up to 50 waypoints
int increment = 0;
#define autopilot 13
void gesturecontroll();
void getGPS();
void getCompass();
void setWaypoint();
void move();
int blueToothVal;
void setup()
{ Serial.begin(9600); // Serial 0 is for communication with the computer
S2.begin(9600); // Serial 2 is for GPS communication at 9600 baud - DO NOT MODIFY - Ublox Neo 6m
Serial.println("ESPNow/Basic/Slave Example");
//Set device in AP mode to begin with
WiFi.mode(WIFI_AP);
// configure device AP mode
// This is the mac address of the Slave in AP Mode
esp_wifi_set_mac(ESP_IF_WIFI_STA, &mac[0]);
Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
// Init ESPNow with a fallback logic
if (esp_now_init()!=0) {
Serial.println("*** ESP_Now init failed");
while(true) {};
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info.
esp_now_register_recv_cb(OnDataRecv);
Serial.print("Aheloiioi");
// Extras////////////////////////////////////////////////////////////////////////////////////
pinMode(autopilot, INPUT);
}
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
memcpy(&myData, data, sizeof(myData));
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.print("Last Packet Recv from: "); Serial.println(macStr);
Serial.print("Last Packet Recv Data: ");
Serial.println(myData.x);
Serial.println(myData.y);
Serial.println("");
Serial.println();
//move();
Serial.println();
}
//********************************************************************************************************
// Main Loop
void loop()
{ if (autopilot == HIGH)
{
// going for manual control, BUT WHAT SHOULD I PUT HERE?
}
else
{
getGPS(); // Update the GPS location
getCompass(); // Update the CompaSerial Heading
Ping(); // Use at your own discretion, this is not fully tested
}
}
I needed to use software serial in my MSP-EXP430G2ET board which uses MSP430G2553 microcontroller. I used msp430g2xx3_ta_uart9600.c file in TI's sofware library. In this code UART pins configured as P1.1 and P1.2. By the way these pins are original RX-TX pins of MSP430.
That is working pretty well, but when I changed the pins to some other pins it does not work. This is the code I am working on. In this code I tried to configure RX-TX pins as P2.1-P2.2
#include <msp430.h>
//------------------------------------------------------------------------------
// Hardware-related definitions
//------------------------------------------------------------------------------
#define UART_TXD BIT1 // TXD on P2.1 (Timer0_A.OUT0)
#define UART_RXD BIT2 // RXD on P2.2 (Timer0_A.CCI1A)
//------------------------------------------------------------------------------
// Conditions for 9600 Baud SW UART, SMCLK = 1MHz
//------------------------------------------------------------------------------
#define UART_TBIT_DIV_2 (1000000 / (9600 * 2))
#define UART_TBIT (1000000 / 9600)
//------------------------------------------------------------------------------
// Global variables used for full-duplex UART communication
//------------------------------------------------------------------------------
unsigned int txData; // UART internal variable for TX
unsigned char rxBuffer; // Received UART character
//------------------------------------------------------------------------------
// Function prototypes
//------------------------------------------------------------------------------
void TimerA_UART_init(void);
void TimerA_UART_tx(unsigned char byte);
void TimerA_UART_print(char *string);
//------------------------------------------------------------------------------
// main()
//------------------------------------------------------------------------------
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
if (CALBC1_1MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set DCOCLK to 1MHz
DCOCTL = CALDCO_1MHZ;
P2OUT = 0x00; // Initialize all GPIO
P2SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins
P2DIR = 0xFF & ~UART_RXD; // Set all pins but RXD to output
P1OUT = 0x00;
P1SEL = 0x00;
P1DIR = 0xFF;
__enable_interrupt();
TimerA_UART_init(); // Start Timer_A UART
TimerA_UART_print("G2xx2 TimerA UART\r\n");
TimerA_UART_print("READY.\r\n");
for (;;)
{
// Wait for incoming character
// __bis_SR_register(LPM0_bits);
// TimerA_UART_print("AT\r\n\n");
// __delay_cycles(100000);
}
}
//------------------------------------------------------------------------------
// Function configures Timer_A for full-duplex UART operation
//------------------------------------------------------------------------------
void TimerA_UART_init(void)
{
TACCTL0 = OUT; // Set TXD Idle as Mark = '1'
TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int
TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode
}
//------------------------------------------------------------------------------
// Outputs one byte using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_tx(unsigned char byte)
{
while (TACCTL0 & CCIE); // Ensure last char got TX'd
TACCR0 = TAR; // Current state of TA counter
TACCR0 += UART_TBIT; // One bit time till first bit
TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int
txData = byte; // Load global variable
txData |= 0x100; // Add mark stop bit to TXData
txData <<= 1; // Add space start bit
}
//------------------------------------------------------------------------------
// Prints a string over using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_print(char *string)
{
while (*string) {
TimerA_UART_tx(*string++);
}
}
//------------------------------------------------------------------------------
// Timer_A UART - Transmit Interrupt Handler
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
static unsigned char txBitCnt = 10;
TACCR0 += UART_TBIT; // Add Offset to CCRx
if (txBitCnt == 0) { // All bits TXed?
TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt
txBitCnt = 10; // Re-load bit counter
}
else {
if (txData & 0x01) {
TACCTL0 &= ~OUTMOD2; // TX Mark '1'
}
else {
TACCTL0 |= OUTMOD2; // TX Space '0'
}
txData >>= 1;
txBitCnt--;
}
}
//------------------------------------------------------------------------------
// Timer_A UART - Receive Interrupt Handler
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A1_VECTOR
__interrupt void Timer_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) Timer_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
static unsigned char rxBitCnt = 8;
static unsigned char rxData = 0;
switch (__even_in_range(TA0IV, TA0IV_TAIFG)) { // Use calculated branching
case TA0IV_TACCR1: // TACCR1 CCIFG - UART RX
TACCR1 += UART_TBIT; // Add Offset to CCRx
if (TACCTL1 & CAP) { // Capture mode = start bit edge
TACCTL1 &= ~CAP; // Switch capture to compare mode
TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0
}
else {
rxData >>= 1;
if (TACCTL1 & SCCI) { // Get bit waiting in receive latch
rxData |= 0x80;
}
rxBitCnt--;
if (rxBitCnt == 0) { // All bits RXed?
rxBuffer = rxData; // Store in global variable
rxBitCnt = 8; // Re-load bit counter
TACCTL1 |= CAP; // Switch compare to capture mode
__bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR)
}
}
break;
}
}
When you are using the hardware UART module, you have to use one of those pins that the module is connected to (P1.1/P1.2 for UCA0RXD/UCA0TXD).
When you are using a hardware timer module, you have to use one of those pins that the module is connected to (P1.1 or P1.5 for TA0.0, P1.2 or P1.6 or P2.6 for TA0.1).
Some other pins can be used if you use the other timer module. But P2.1/P2.2 are both connected to the same CCR of TimerA1.
I try to achieve an USART communication. So I connect the RX of my STM32f1 with his TX.
Also I write a program for this communication. This code is composed of the following components:
RCC configuration
GPIO configuration
USART configuration
Send and receive of a string
Comparison between the sent string and the received string
Test if the communication succeeded => LED4 turn on else the LED3 turn on
The problem is in all cases the LED3 turns on. It means that the data transmission failed.
With my IDE (IAR's Embedded Workbench) I compile this program code:
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32_eval.h"
/* Private typedef -----------------------------------------------------------*/
typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;
/* Private define ------------------------------------------------------------*/
#define USARTy USART1
#define USARTy_GPIO GPIOA /* PORT name*/
#define USARTy_CLK RCC_APB2Periph_USART1
#define USARTy_GPIO_CLK RCC_APB2Periph_GPIOA
#define USARTy_RxPin GPIO_Pin_10/* pin Rx name*/
#define USARTy_TxPin GPIO_Pin_9 /* pin Tx name*/
#define USARTz USART2
#define USARTz_GPIO GPIOA/* PORT name*/
#define USARTz_CLK RCC_APB1Periph_USART2
#define USARTz_GPIO_CLK RCC_APB2Periph_GPIOA
#define USARTz_RxPin GPIO_Pin_3/* pin Rx name*/
#define USARTz_TxPin GPIO_Pin_2/* pin Tx name*/
#define TxBufferSize (countof(TxBuffer))
/* Private macro -------------------------------------------------------------*/
#define countof(a) (sizeof(a) / sizeof(*(a)))
/* Private variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure;
uint8_t TxBuffer[] = "Bufferrr";
uint8_t RxBuffer[8];
__IO uint8_t TxConteur = 0, RxConteur = 0;
volatile TestStatus TransferStatus = FAILED;
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength);
__IO uint8_t index = 0;
GPIO_InitTypeDef GPIO_InitStructure;
int main(void)
{
STM_EVAL_LEDInit(LED1);
STM_EVAL_LEDInit(LED2);
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
/* System Clocks Configuration */
RCC_Configuration();
/* Configure the GPIO ports */
GPIO_Configuration();
USART_InitStructure.USART_BaudRate = 230400 /*115200*/;
USART_InitStructure.USART_WordLength =USART_WordLength_8b ;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure USARTy */
USART_Init(USART1,&USART_InitStructure);
/* Enable the USARTy */
USART_Cmd(USART1,ENABLE);
while(TxConteur < TxBufferSize)
{
/* Send one byte from USARTy to USARTz */
USART_SendData(USARTy, TxBuffer[TxConteur++]);
/* Loop until USARTy DR register is empty */
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{
}
/* Store the received byte in RxBuffer */
RxBuffer[RxConteur++] = USART_ReceiveData(USARTy) & 0xFF;
}
/* Check the received data with the send ones */
TransferStatus = Buffercmp(TxBuffer, RxBuffer, TxBufferSize);
/* TransferStatus = FAILED, if the data transmitted from USARTy and
received by USARTz are different */
if (TransferStatus == FAILED)
{
STM_EVAL_LEDOn(LED3);
}
else
{
STM_EVAL_LEDOn(LED4);
}
while (1)
{
}
}
void RCC_Configuration(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure1,GPIO_InitStructure2;
/* Configure USARTy Rx as input floating */
GPIO_InitStructure1.GPIO_Pin =GPIO_Pin_10;
GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure1);
/* Configure USARTy Tx as alternate function push-pull */
GPIO_InitStructure2.GPIO_Pin =GPIO_Pin_9;
GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure2);
/* Configure USARTz Tx as alternate function push-pull */
}
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
while(BufferLength--)
{
if(*pBuffer1 != *pBuffer2)
{
return FAILED;
}
pBuffer1++;
pBuffer2++;
}
return PASSED;
}
Like explained in a comment by Hans Passant, the OP was testing the flag USART_FLAG_TC (Transmission Completed) instead of the flag USART_FLAG_RXNE (RX buffer Not Empty).