Tablica z pomiarami

0

Witam,
Stworzyłem na mikroprocesorze AVR pomiar odległości (czujnik ultradźwiękowy) i chciałbym wyświetlać wykres odległości w funkcji kolejnych próbek na wyświetlaczu 128x64. Zakres pomiarowy to 2-250 cm. Z racji, że szerokość wyświetlacza to 128 pixeli (od 0 do 128), więc pomyślałem, że stworzę tablicę 128 elementową, gdzie będę zapisywał pomiary i wyświetlał je na wyświetlaczu, a następnie gdy 128 element tablicy przyjmie wartość niezerową to, elementom tablicy tab[i] nadam wartość tab [i+1] (przesunięcie próbek o jedną w lewo, zapominanie tej najstarszej i nadanie wartości tab[127] aktualnej wartości itp. I teraz pytanie, czy można to zrobić lepiej? Bo przepisywanie co każdy pomiar 127 elementów tablicy jest chyba mało optymalnym rozwiązaniem.

Dodam, że w celu wyświetleniu danego piksela na wyświetlaczu wystarczy podać, jego współrzędne: x = (0,127) y= (0,63) => przedziały
Z racji, że wysokość zawiera 64 piksele a mój wynik maksymalnie osiąga wartość 250, to należy przeskalować pomiar, dzieląc go przez 4, wtedy 1pikel będzie odpowiadał za 4 cm.

mój pomysł:

 
int main(){

int tab [ 128];

// Wyświetlacz pusty, tablica pusta, rozpoczynanie rysowania wykresu

if (tab[127]==0) //jeśli ekran czysty, rysuj wykres, aż ostatni element tablicy (pixel) przyjmie jakąś wartość
{
for (int i =0; i<128; i++)
{

pomiar(); //wywolanie funkcji która wykona pomiar i do zmiennej odleglosc przypisze wartość z zakresu 2 - 250
tab[i]=odleglosc/4;
rysuj (i, tab[i]); //funcja rysuje piksel na wsp (x,y), gdzie (0,0) to lewy dolny róg wyświetlacza

_delay_ms(100); // opóźnienie 10 pomiarów na sekundę 

}

else  //cały wyświetlacz zapełniony, teraz trzeba zapomnieć próbkę tab[0] i wpisać nową do tab[127] i znowu wyświetlić wszystkie
{

for (int i=0; i<127; i++) //przepisywanie tablicy,  element tab[126] = tab[127], a więc wszystko przesunięte o 1 w lewo
{

tab[i]=tab[i+1];


}
pomiar();

tab[127]=odleglosc; //mamy już cala tablice przesuniętą o 1 w lewo + nowy pomiar


for (int i =0; i<128; i++)
{

rysuj (i, tab[i]/4);

}
_delay_ms(100); 

}

}

Moje pytanie, jak można zrobić to lepiej? Słyszałem, że jest coś takiego jak bufor kołowy, ale nie mam pojęcia jak go wykorzystać, bo jestem początkujący w programowaniu w C.
Może ewentualnie jakieś inne pomysły?

2

Ale tutaj jest proste rozwiązanie! Zadeklaruj sobie zmienną na 'start' i używaj jej zawsze modulo 128 (rozmiar tablicy). Zawsze inkrementujesz i zapisujesz do odpowiedniego indeksu.
A rysując lecisz od 'start' do końca tablicy i potem od początku do "start".

Unikniesz przepisywania i masz upośledzony bufor kołowy ;)

1
  1. zapoznaj się z pojęciem formatowania kodu: http://4programmers.net/Forum/998482
  2. pozbądź się smrodku przy inkrementacji: http://4programmers.net/Forum/1101404
  3. Możesz to nawet do osobnej funkcji wsadzić:
const unsigned bitsize=7,size=1<<bitsize,mask=size-1;
static unsigned index=0;
static int tab[size]={0};
tab[index]=pomiar()/4; /* niech pomiar zwraca ta wartość, zmienne globalne nie są dobrym pomysłem */
index=(index+1)&mask;
for(unsigned i=0;i<size;++i) rysuj(i,tab[(index+i)&mask]);
0
xfin napisał(a):

Ale tutaj jest proste rozwiązanie! Zadeklaruj sobie zmienną na 'start' i używaj jej zawsze modulo 128 (rozmiar tablicy). Zawsze inkrementujesz i zapisujesz do odpowiedniego indeksu.
A rysując lecisz od 'start' do końca tablicy i potem od początku do "start".

Unikniesz przepisywania i masz upośledzony bufor kołowy ;)

Tak myślałem, że jest tutaj lepsze rozwiązanie. A czy byłbyś w stanie przemienić kod mojej funkcji na tą uproszczoną, bo mimo, że wiem o co tu może chodzić, to nie wiem za bardzo jak przelać to na język C. Byłbym baaardzo wdzięczny.

0
_13th_Dragon napisał(a):

zapoznaj się z pojęciem formatowania kodu: http://4programmers.net/Forum/998482

  1. pozbądź się smrodku przy inkrementacji: http://4programmers.net/Forum/1101404
  2. Możesz to nawet do osobnej funkcji wsadzić:
const unsigned bitsize=7,size=1<<bitsize,mask=size-1;
static unsigned index=0;
static int tab[size];
tab[index]=pomiar()/4; /* niech pomiar zwraca ta wartość, zmienne globalne nie są dobrym pomysłem */
index=(index+1)&mask;
for(unsigned i=0;i<size;++i) rysuj(i,tab[(index+i)&mask]);

I to jest już gotowa funkcja, która realizuje wszystko, co ja napisałem wyżej? :D

0
mg_1990 napisał(a):
_13th_Dragon napisał(a):

zapoznaj się z pojęciem formatowania kodu: http://4programmers.net/Forum/998482

  1. pozbądź się smrodku przy inkrementacji: http://4programmers.net/Forum/1101404
  2. Możesz to nawet do osobnej funkcji wsadzić:
const unsigned bitsize=7,size=1<<bitsize,mask=size-1;
static unsigned index=0;
static int tab[size];
tab[index]=pomiar()/4; /* niech pomiar zwraca ta wartość, zmienne globalne nie są dobrym pomysłem */
index=(index+1)&mask;
for(unsigned i=0;i<size;++i) rysuj(i,tab[(index+i)&mask]);

I to jest już gotowa funkcja, która realizuje wszystko, co ja napisałem wyżej? :D

Czyli całość będzie wyglądała tak?


void wykres()
{
const unsigned bitsize=7,size=1<<bitsize,mask=size-1;
static unsigned index=0;
static int tab[size];
tab[index]=pomiar()/4; /* niech pomiar zwraca ta wartość, zmienne globalne nie są dobrym pomysłem */
index=(index+1)&mask;
{for(unsigned i=0;i<size;++i) rysuj(i,tab[(index+i)&mask]);
}

int main()
{

while(1)
{
wykres();
_delay_ms(100);
}

No i oczywiście muszę umieścić funkcję pomiar i rysuj.
Teraz muszę rozkminić jak działa to, co napisałeś, bo póki co nie mam pojęcia.
Jakich rzeczy użyłeś, o których muszę doczytać, żeby zrozumieć co się dzieje?

1

Może zacznij od jakiegoś kursu podstaw, bo nawet nie wiesz gdzie klamerki wstawić:

void wykres()
  {
   const unsigned bitsize=7,size=1<<bitsize,mask=size-1;
   static unsigned index=0;
   static int tab[size];
   tab[index]=pomiar()/4; // NIE ZAPOMNIJ ZMIENIĆ TEN pomiar
   index=(index+1)&mask;
   for(unsigned i=0;i<size;++i) rysuj(i,tab[(index+i)&mask]);
  }

int main()
  { 
   for(;;_delay_ms(100)) wykres();
  }
0

Niestety nie mogę w funkcji pomiar podzielić od razu wartości zwracanej przez funkcję przez 4, ponieważ potrzebna jest mi ona także do wyświetlenia dokładnej odległości na wyświetlaczu. Czy może być tak?

 

u_int8_t odleglosc;

void wykres()
  {
   const unsigned bitsize=7,size=1<<bitsize,mask=size-1;
   static unsigned index=0;
   static int tab[size];
   pomiar();
   tab[index]=odleglosc/4;
   index=(index+1)&mask;
   for(unsigned i=0;i<size;++i) rysuj(i,tab[(index+i)&mask]);
  }
 
int main()
  { 
   for(;;_delay_ms(100)) wykres();
  }

0
mg1990 napisał(a):

Niestety nie mogę ...

  • należy odróżniać "nie mogę" od "nie umiem"
mg1990 napisał(a):

... w funkcji pomiar podzielić od razu wartości zwracanej przez funkcję przez 4 ...

  • to dzielenie: pomiar()/4 nie jest w funkcji pomiar, tylko dzielnie wykonane na wartości zwróconej.
mg1990 napisał(a):

... ponieważ potrzebna jest mi ona także do wyświetlenia dokładnej odległości na wyświetlaczu ...

  • co ma jedno do drugiego?
mg1990 napisał(a):

Czy może być tak?

  • nie używaj zmiennych globalnych, mocno na tym się przejedziesz i nie raz dopóki nie zaprzestaniesz ich użycia.

Pokaż tą funkcje pomiar - pewnie też 10 krotnie się skróci.

0

Dzięki wielkie za pomoc, już ogarniam o co chodzi w Twoim kodzie i jest to świetne rozwiązanie. Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1