A jednak coś się wykrzaczyło
Wynik pomiaru ma być przedstawiony na wyświetlaczu LCD 2x16 z którym komunikacja przebiega po magistrali I2C.
Jeśli skorzystam z Serial Monitora żeby wyświetlić wyniki to działa to bez problemu i otrzymuję wyniki na w ArduinoIDE w Serial Monitorze.
Jeśli jednak chcę wykorzystać wyświetlacz LCD to wyświetla się na nim tylko:
"Czas: 8750.00"
"Odleglosc: 301.0"
Nic się wogóle nie zmienia na wyświetlaczu. Wyświetlacz jest sprawdzony odpalałem na nim inny program, żeby go sprawdzić i wszystko było okej.
Przy próbie zmiany pierwszego wypisu:
lcd.print("Czas:");
na
lcd.print("Time:");
Nic się nie zmienia na ekranie.
Poniżej kod programu:
// jest to gotowy program ultradzwiekowego miernika odleglosci
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
volatile uint16_t time1 = 0;
volatile uint16_t time_wait = 0;
volatile uint8_t perm_on = 0;
double czas_us = 0;
double odleglosc = 0;
// ISR informujący o niepoprawnej nazwie wektora
ISR(BADISR_vect)
{
time1 = 25;
}
// ISR sterujący generowaniem paczki w odpowiednich momentach
ISR(TIMER1_COMPA_vect)
{
time1++;
if (time1 == 52000) //48000 kolejna paczka po 600 ms ( w tym czasie trzeba się wyrobić z wypisaniem na ekranie)
{
// Po osiągnięciu 48000 razy wartości TOP przez timer zmień stan bitu podłączającego/odłączającego OC1B na przeciwny
TCCR1A |= (1 << COM1B0);
// wyzeruj zmienną timer1
time1 = 0;
}
if (time1 == 8 ) // 4 * 25us = 100 us ( time1 * 25 / 2 = czas paczki impulsów)
{
// Po osiągnięciu 12 razy wartości TOP przez timer zmień stan bitu podłączającego/odłączającego OC1B na przeciwny
TCCR1A &= ~(1 << COM1B0);
}
}
ISR(PCINT0_vect) {
if ((time1 > 82) && perm_on) // jeśli odbiornik na początku łapie jakieś zakłócenie można zwiększyć time1 > x, odbędzie się to jednak kosztem minimalnej zmierzone odległości
{
time_wait = time1;
perm_on = 0;
}
}
void setup() {
_delay_ms(500);
// Rozpoczęcie transmisji szeregowej
Serial.begin(9600);
// Ustawienie PB2 jako wyjście
DDRB |= (1 << PB2);
// Ustawienie PB5 jako wejście
DDRB &= ~(0 << PB5);
// Wyczyszczenie poprzedniej zawartości rejestrów
PCICR = 0;
PCMSK0 = 0;
// Załączenie przerwań dla PCINT7..0
PCICR |= (1 << PCIE0);
// Załączenie przerwania na pinie PB5 (PCINT5)
PCMSK0 |= (1 << PCINT5);
// Wyczyszczenie poprzedniej zawartości rejestrów
TCCR1B = 0;
TCCR1A = 0;
// Tryb CTC
TCCR1A |= (1 << COM1B0);
// Prescaler: CS11 --> 8, CS10 + CS11 --> 64, CS12 --> 256
TCCR1B |= (1 << WGM12) | (1 << CS11);
// Wartość TOP
OCR1A = 24;
TIMSK1 |= (1 << OCIE1A);
perm_on = 1;
// Globalne włączenie obsługi przerwań
sei();
}
void loop() {
_delay_ms(350);
lcd.clear();
czas_us = (double)time_wait * 25 / 2;
odleglosc = 0.0344 * czas_us; // Odleglosc w centymetrach
Serial.println("Czas: ");
Serial.println(czas_us , 4); // Wypisanie czasu w mikrosekundach (4 cyfry po przecinku)
Serial.println("Odleglosc: ");
Serial.println(odleglosc , 2); // Wypisanie odleglosci w centymetrach (2 cyfry po przecinku)
lcd.setCursor(0,0);
lcd.print("Czas:");
lcd.setCursor(6,0);
lcd.print(czas_us, 4);
lcd.setCursor(0,1);
lcd.print("Odleglosc:");
lcd.setCursor(11,1);
lcd.print(odleglosc, 2);
perm_on = 1;
return(0);
}
Co może być przyczyną takiego zachowania programu? Gdzie szukać przyczyny? Proszę o pomoc w tym temacie.
------------------------ [ Dodano po: 5 minutach ]Czy byłoby możliwe, że przerwanie ISR(TIMER1_COMPA_vect) lub ISR(PCINT0_vect) przychodzi tak szybko, że dane nie zdążą być przesłane do wyświetlacza?