使用ATMEGA328P在LCD矩阵上显示文本
背景和目标
我正在使用超声波传感器(HC-SR04)和ATMEGA328P(Arduino)和三个级联的Max7219 LCD矩阵之间的SPI通信进行简单的AVR C项目。系统的目的是使用超声传感器检测和测量距离,并同时在LCD矩阵上显示适当的消息。
有效的是,
我可以执行两个组件的主要功能 分别 。我可以使用HC-SR04检测并测量距离,并且可以在LCD矩阵上显示文本并滚动文本。 HC-SR04反复测量每5ms的距离。
问题问题
当我想同时执行两个功能 时,问题就会上升。发生的事情是,文本消息是在LCD矩阵上反复显示的,但没有完整。我了解这是因为我使用超声传感器反复测量距离。我的猜测会中断,但是我不确定如何解决这个问题。
是否有一种方法可以在LCD上完全显示“ 最后测量的距离”,而仍在测量距离?
代码(主要部分):
// GLOBALS
volatile unsigned short echo_time;
volatile unsigned short distance;
// Text to display to LCD
char text[25] = "DEFAULT";
// Fire sensor
void fire_sensor()
{
// Fire the trigger pin
PORTD |= (1 << TRIG_PIN);
// Wait for 10 microseconds in reference to the data sheet
_delay_us(10);
// Toggle the trigger pin to turn off
PORTD &= ~(1 << TRIG_PIN);
}
// Measure distance
void measure_distance()
{
// Wait until echo pin is low and timer counter has changed
while (echo_time == 0);
// Calculate the distance in centimeters
distance = echo_time/58;
if (distance <= 60)
{
strcpy(text,"VEHICLE DETECTED");
PORTB = 0b00000001; // Turn DEBUG LED ON
}
else
{
strcpy(text,"DETECTED NOTHING");
PORTB = 0b00000000; // Turn DEBUG LED OFF
}
}
// *************************** MAIN *************************** //
int main(void)
{
// Enable interrupts
sei();
// Initialise components
EchoSetup();
SPISetup();
InitMatrix();
InitBuffer();
ClearMatrix();
// Get length of text
size_t length = strlen(text);
/* Replace with your application code */
while (1)
{
fire_sensor();
measure_distance();
_delay_ms(5);
// Display to LCD matrix character by character
for (uint16_t i = 0; i < length; i++)
{
PushCharacter(text[i] - 32);
PushBuffer(0x00); // Add empty column after character for letter spacing
}
}
}
// *************************** INTERRUPTS *************************** //
ISR(INT0_vect)
{
// ECHO is high (signal has come back) stop counter
if(PIND &(1 << PIND3)){
// Reset the counter
TCNT1 = 0;
}
else
{
// ECHO pin is low and the counter starts
echo_time = TCNT1;
}
}
Background and objective
I am working on a simple AVR C project with an ultrasonic sensor (HC-SR04) and SPI communication between the ATmega328P (Arduino) and three cascaded MAX7219 LCD matrix. The objective of the system is to detect and measure the distance using the ultrasonic sensor and display an appropriate message on the LCD matrix simultaneously.
What's working
I can perform the main functionality of both components separately. I can detect and measure distance with the HC-SR04 and I can display the text on the LCD matrix and scroll the text as well. The HC-SR04 repeatedly measures the distance roughly every 5ms.
Problem
The problem rises when I want to perform both functionalities simultaneously. What happens is that the text message is displayed repeatedly on the LCD matrix but not in full. I understand this is because I repeatedly measure the distance using the ultrasonic sensor. My guess would be interrupts, however I am not sure how to tackle this issue.
Is there a way of displaying the "last measured distance" fully on the LCD whilst still measuring distance?
The code (main parts):
// GLOBALS
volatile unsigned short echo_time;
volatile unsigned short distance;
// Text to display to LCD
char text[25] = "DEFAULT";
// Fire sensor
void fire_sensor()
{
// Fire the trigger pin
PORTD |= (1 << TRIG_PIN);
// Wait for 10 microseconds in reference to the data sheet
_delay_us(10);
// Toggle the trigger pin to turn off
PORTD &= ~(1 << TRIG_PIN);
}
// Measure distance
void measure_distance()
{
// Wait until echo pin is low and timer counter has changed
while (echo_time == 0);
// Calculate the distance in centimeters
distance = echo_time/58;
if (distance <= 60)
{
strcpy(text,"VEHICLE DETECTED");
PORTB = 0b00000001; // Turn DEBUG LED ON
}
else
{
strcpy(text,"DETECTED NOTHING");
PORTB = 0b00000000; // Turn DEBUG LED OFF
}
}
// *************************** MAIN *************************** //
int main(void)
{
// Enable interrupts
sei();
// Initialise components
EchoSetup();
SPISetup();
InitMatrix();
InitBuffer();
ClearMatrix();
// Get length of text
size_t length = strlen(text);
/* Replace with your application code */
while (1)
{
fire_sensor();
measure_distance();
_delay_ms(5);
// Display to LCD matrix character by character
for (uint16_t i = 0; i < length; i++)
{
PushCharacter(text[i] - 32);
PushBuffer(0x00); // Add empty column after character for letter spacing
}
}
}
// *************************** INTERRUPTS *************************** //
ISR(INT0_vect)
{
// ECHO is high (signal has come back) stop counter
if(PIND &(1 << PIND3)){
// Reset the counter
TCNT1 = 0;
}
else
{
// ECHO pin is low and the counter starts
echo_time = TCNT1;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议将MEATH_DISTANCE()非阻滞。
在您的时循环中,您不再等待结果准备就绪,而是反复检查它是否已准备就绪并显示结果。
这仍然不是“干净的代码”,因为某些职责在功能之间松散耦合。但是改进这样的代码具有经验。
I would suggest to make measure_distance() non-blocking.
In your while loop, you no longer wait for the result to be ready but repeatedly check if it "was" ready and display the result.
This is still not "clean code" because some responsibilities are loosely coupled between functions. But improving code like this comes with experience.