Arduino Rfid reading delay while blinking LED [closed] - input

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have a RFID reader which is connected to the Arduino.. and successfully receives tag number to serial monitor. But when I put the LED blink inside the loop, then the rfid reading is delayed: it receives tag numbers one by one after each blink.
Code is below. I think I should use multi-threading or interrupts, but I don't know how to do it.
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
pinMode(2, OUTPUT);
}
void loop() {
// blink led in pin 2
digitalWrite(2, HIGH);
delay(1000);
digitalWrite(2, LOW);
delay(1000);
//Below Serial1.available() checks my rfid reader input signal and print on serial monitor of Arduino.. and Serial1 is on pin RX1 19 (RX1 19 is the default pin for serial1 defined by Arduino developers "http://arduino.cc/en/reference/serial#.Uyvbq6iSzIg") to which my rfid reader is connected
if (Serial1.available()) {
int i = Serial1.read();
Serial.print(i);
}
}

There is an Arduino file called "Blink without Delay" It is included with the Arduino examples and I have linked to it. Do yourself a favor and take ten minutes to read through the tutorial and the code in order to understand what it does.

You can use the timer of the Arduino and the appropriate interrupts. So something like this here:
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
pinMode(2, OUTPUT);
/* Initialize timer, e.g. timer1 */
noInterrupts(); //disable interrupts
TCCR1A = 0; //Timer1 control register A
TCCR1B = 0; //Timer1 control register B
TCNT1 = 0; //Counter of timer1
OCR1A = 15625; //Timer1 compare match register
TCCR1B |= (1<<WGM12); //Set timer1 in CTC mode
/* Define prescaler with 1024. If the clock is 16 MHz, then timer1 will run
* with 16 MHz / 1024 = 15625 Hz --> 64 us, to get one second, we
* need 15625 cycles, which is the OCR1A register */
TCCR1B |= (1<<CS10) | (1<<CS12); // clock prescaler = 1024
TIMSK1 |= (1<<OCIE1A); //enable timer compare interrupt
interrupts(); //enable interrupts
}
//This routine is called every time, timer1 counter reaches the compare register
ISR(Timer1_COMPA_vect) {
digitalWrite(2, digitalRead(2) ^ 1); //toggle LED
}
//the loop
void loop() {
if (Serial1.available()) {
int i = Serial1.read();
Serial.print(i);
}
}

Related

Arduino C++ Running two while loops at the same time

I am trying to figure out how to run 2 while loops at the same time but in the easiest way possible?
I want one loop to check for a signal from the joystick that i connected to the Arduino.I want the second loop to display a face in the LCD screen and i want it to blink every 5 minutes.(I know it sounds weird)
The term you are looking for here is called multi-threading. The first thread will be for your joystick loop and the second will be fore your LCD screen. Depending on the board you are using, the strain added to the hardware will be different.
Regardless of board type, you can use a library such as protothreads to accomplish this. Here is the code from Digikey's tutorial on multithreading in arduino programs.
#include "protothreads.h"
#define LED_1 2
#define LED_2 3
pt ptSlowBlink;
pt ptFastBlink;
int fastBlinkThread(struct pt* pt)
{
PT_BEGIN(pt);
while(true)
{
digitalWrite(LED_1, HIGH);
PT_SLEEP(pt, 250);
digitalWrite(LED_1, LOW);
PT_SLEEP(pt, 250);
}
PT_END(pt);
}
int slowBlinkThread(struct pt* pt)
{
PT_BEGIN(pt);
while(true)
{
digitalWrite(LED_2, HIGH);
PT_SLEEP(pt, 1000);
digitalWrite(LED_2, LOW);
PT_SLEEP(pt, 1000);
}
PT_END(pt);
}
void setup()
{
PT_INIT(&ptSlowBlink);
PT_INIT(&ptFastBlink);
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
}
void loop()
{
PT_SCHEDULE(slowBlinkThread(&ptSlowBlink));
PT_SCHEDULE(fastBlinkThread(&ptFastBlink));
}
If the board you're using support Mbed OS, then there are also native features that will provide a significant increase in performance over the code above. It comes with some added learning curve but if you want to learn more the above tutorial also has a small introduction to Mbed OS multithreading.

HAL_UART_RxCpltCallback() not getting executed

I want to send 10 bytes of data through UART loopback by interrupt mode. Though I'm able to receive the data, I don't understand why my HAL_UART_RxCpltCallback() is not getting executed. But my HAL_UART_TxCpltCallback(), is getting executed every time after a byte of data is transferred. I've generated code through cubeMX. I've enabled the USART2 global interrupt. My Control Register(CR1) for my USART2 is 0x300c. That is, UE,M,TE,RE bits are only set. The TXIE, TCIE bits are NOT set in the CR1 Register.
Now,
What does "global" in global interrupt mean here? Does that mean an interrupt is generated from any one of the 10 sources(mentioned in the data sheet like, Tx complete, Rx buffer full etc)?
None of the bits corresponding to interrupts are enabled in CR1 register. But the control is going to HAL_UART_TxCpltCallback() every time it transfers a byte of data. Why does this happen?
Please unveil the mystery.
PS: I'm using STM32F407G-DISC1 board, Attolic Truestudio IDE, Ubuntu 16.04 OS.
UART_HandleTypeDef huart2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
uint8_t tx_data[] = {0,1,2,3,4,5,6,7,8,9};
uint8_t rx_data[10];
int main(void)
{
int i=0;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
while (1)
{
HAL_UART_Transmit_IT(&huart2, &tx_data[i], 10);
HAL_Delay(1500);
HAL_UART_Receive_IT(&huart2, &rx_data[i] , 10);
HAL_Delay(1500);
if((xferCnt==10) || (rxCnt==10))
break;
else
i++;
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
xferCnt++;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
rxCnt++;
}

Interrupt handler won't run

I'm working on an stm32l467 and trying to run an ISR when i push the user-push-button. Everything looks to be setup correctly. I have looked at the registers in the debugger (Keil uV) and everything looks good, but when i push the button I end up in the default handler and can't understand why the handler is not running.
Running in the debugger i can see that when i push the button, i get an interrupt-pending (EXTI->PR1) flag, but the code then jumps to the the default handler. I can't see what i'm missing. I know there are easier ways to setup interrupts using the HAL layer, i'm just trying to understand what registers must be accessed from a low-level.
Can anyone suggest a missing step to this?
#include <stm32l4xx.h>
#define DELAY 1
void delay1Hz(void);
bool buttonInterrupt = false;
int main(void)
{
__disable_irq();
/* Configure the clocks */
RCC->CR &= 0xFFFFFF07; //Clear ~MSIRANGE bits and MSIRGSEL bit
RCC->CR |= 0x00000088; //Set MSI to 16MHz and MSIRGSEL bit
RCC->AHB2ENR |= 0x00000001; //Enable PA5 clocks
/* Enable PA0 for output */
GPIOA->MODER &= 0xFFFFF3FF; //Clear GPIOA[5] MODER bits
GPIOA->MODER |= 0x00000400; //Enable GPIOA[5] for output
RCC->AHB2ENR |= 0x4; //ENABLE GPIOC port clk
GPIOC->MODER &= 0xF3FFFFFF; //Clear GPIOC[13] for input mode
RCC->APB2ENR |= 1; //Enable SYSCFG clk
SYSCFG->EXTICR[3] &= ~0x00F0; //CLEAR_BIT the EXTI[13] bits
SYSCFG->EXTICR[3] |= 0x20; //Enable GPIOC for EXTI[13]
EXTI->IMR1 |= 0x2000; //Unmask EXTI13
EXTI->FTSR1 |= 0x2000; //Enable falling edge trigger on pb
NVIC_EnableIRQ(EXTI15_10_IRQn); //Enable EXTI15-to-10 interrupts
__enable_irq();
for (;;)
{
if(buttonInterrupt == true) {
//flash LED's (doesn't get here)
}
}
}
void initTim2() {
//timer 2 code - not causing a problem
}
void delay1Hz() {
//delay code - not interrupt controlled
}
/* This doesn't run */
void EXTI15_10_IRQHandler(void) {
buttonInterrupt = true;
EXTI->PR1 = 0x2000;
}
Never mind: There seems to be some problem with a delay i have with timer-2. It's not using interrupts, so i'm surprised it's causing trouble. But if i take it out and use a different delay, the interrupt from the above code works fine. It's an odd one.

Cortex M-0: Simple external interrupt

I'm trying to set up an external interrupt on my LPC812 uC. I've made the following code
#include "LPC8xx.h"
#define RLED 7 // red LED
bool pause = false;
void PININT0_IRQHandler(void)
{
pause = !pause;
}
int main(void) {
LPC_GPIO_PORT->DIR0 |= 1<<RLED; // set pin as output
LPC_GPIO_PORT->SET0 = 1<<RLED;
NVIC_EnableIRQ(PININT0_IRQn);
while (1)
{
if(!pause)
{
LPC_GPIO_PORT->CLR0 = 1<<RLED;
}
}
}
But it isn't working. Am I missing something?
I'm not familiar with NXP MCUs.
But at least place break piont inside PININT0_IRQHandler, to understand clearly that interrupt is not generated.
Also it will be nice to clear interrupt flag inside handler.
Some peripherals need interrupt permission in peripheral registers in addition to NVIC setup.
Did you setup input pin somewhere?
Your code only initialize GPIO 7 pin as output.

ADI BF533 programmable flag interrupt

When I press PF8 button, I want the blackfin goes into a ISR and the counter increases 1.
I should clear or set a bit which indicates the processor has entered the ISR, but I don't know how to clear it.
My processor is BF533.
Here is my code:
// prototype
EX_INTERRUPT_HANDLER(FlagA_ISR);
volatile int count = 0;
void main(void)
{
// Register FlagA ISR to interrupt vector group 12
register_handler(ik_ivg12, FlagA_ISR);
// set direction of programmable flag PF8 to input
*pFIO_DIR &= ~PF8;
ssync();
// interrupt enable PF8
*pFIO_INEN |= PF8;
ssync();
// give interrupt when FIO_FLAG_D PF8 changes
*pFIO_MASKA_D |= PF8;
ssync();
// Bind FlagA interrupt to IVG12
*pSIC_IAR2 |= 0x00005000; // flag A IVG12
ssync();
// Enable PFA in system interrupt mask register
*pSIC_IMASK = 0x00080000;
ssync();
// enable IVG12 in core interrupt mask register
*pIMASK |= 0x00001000;
ssync();
// wait for interrupt
while(count < 5);
printf("5 interrupts received");
}
EX_INTERRUPT_HANDLER(FlagA_ISR)
{
count++;
// Needed to clear or set a bit to indicate that the processor has entered the ISR
}
I have just figured out how to solve this question.
The PFx are connected to the FIO_FLAG. We can clear our interrupt status by clearing FIO_FLAG.
Here is the code:
*pFIO_FLAG_D &= ~PF8;
ssync();
//or, you can try:
*pFIO_FLAG_C |= PF8;
ssync();