Skocz do zawartości
klonyyy

Minisumo Haker2- worklog

Pomocna odpowiedź

Ok dzięki popróbuję zrobić coś z adc.

[ Dodano: 10-09-2012, 17:59 ]

Obiecane zdjęcia ( sorki że tak późno):

To ostatnie zdjęcie przedstawia sam pług, tylko że z kartonu, zrobione na lekcji religii, żeby łatwiej mi było dzisiaj wycinać okienka na czujniki 😉

Plastelina jest tylko chwilowo, jak widać dodałem aluminiowe osłonki na diody, oraz silikony. able od zasilania będą ukryte i na pewno nie będą szły przy kole 😉 Silnkon niesamowicie zbiera brud, co chwila muszę go myć. Jak macie jakieś pytania śmiało pytajcie 😉

EDIT:

#include <avr/io.h>
#include <util/delay.h>

uint16_t pomiar(uint8_t kanal);

int main(void){
 ADMUX |= (1<<REFS0);
 ADCSRA |= (1<<ADEN)| (1<<ADPS1)| (1<<ADPS0);

 DDRA=0x00;

 DDRB=0xff;
 PORTB=0xff;

   uint16_t a=50;

 while(1){

   pomiar(5);

   if(ADCW > a){
     PORTB=0xFF;

   }

   if(ADCW < a){
     PORTB=0x00;
   }

 }
}

uint16_t pomiar(uint8_t kanal){

 ADMUX|=(ADMUX & 0xf8)|kanal;

 ADCSRA|=(1<<ADSC);

 while(ADCSRA & (1<<ADSC));

 return ADCW;
}

Taki kod działa, ale niestety tylko na jeden czujnik - nie mam kompletnie pomysłów jak rozszeżyć go na 2 czujniki - przecież ADCW będzie miało cały czas tą samą wartość, jak pobrać wartość z określonego pinu adc ?

Udostępnij ten post


Link to post
Share on other sites
zrobione na lekcji religii

😃

Fajnie się prezentuje. Jak łączyłeś "dach" z bokami? Bo na zdjęciach nie mogę się dopatrzeć.

Udostępnij ten post


Link to post
Share on other sites

Jak łączyłeś "dach" z bokami? Bo na zdjęciach nie mogę się dopatrzeć.

I dobrze o to chodziło 😉 - sa one lutowane.

Edit:

#include <avr/io.h>
#include <util/delay.h>

uint16_t pomiar(uint8_t kanal);

int main(void){
 ADMUX |= (1<<REFS0);
 ADCSRA |= (1<<ADEN)| (1<<ADPS1)| (1<<ADPS0);

 DDRA=0x00;

 DDRB=0xff;
 PORTB=0xff;

   uint16_t a=50;

 while(1){

   pomiar(5);

   if(ADCW > a){
     PORTB=0xFF;

   }

   if(ADCW  < a){
     PORTB=0x00;
   }

   pomiar(7);

   if(ADCW > a){
     PORTB=0xFF;

   }

   if(ADCW  < a){
     PORTB=0x00;
   }

 }
}

uint16_t pomiar(uint8_t kanal){

 ADMUX=(ADMUX & 0xf8)|kanal;

 ADCSRA|=(1<<ADSC);

 while(ADCSRA & (1<<ADSC));

 return ADCW;

}

Pewnie komuś się przyda- działający kod na dwa czujniki. Problem znowu stanowiła kreseczka (okazało się że w książce Pana Mirka był błąd , dobrze że poinformował o tym na forum 😉 )

[ Dodano: 15-09-2012, 14:14 ]

EDIT:

Nie, jednak potrzebuję pomocy 😋 - jak zczytać wartość adc z wybranego pinu megi ? tak żebym mogł oba odczyty umieścić w jednym warunku? Bo przecież nie zrobięczegoś takiego :

if((ADCW < a) && (ADCW < b ))
PRZOD;

Udostępnij ten post


Link to post
Share on other sites

Sprawdź to:

uint8_t x[7] = {0};
uint16_t adc_read(uint8_t x){

 ADMUX=(ADMUX & 0xf8) | x;
 ADCSRA|=(1<<ADSC);
 while(ADCSRA & (1<<ADSC));

if(ADCW < a) {
czujnik[x] = 1;
if(ADCW > a){
czujnik[x] = 0;
}
}
}
//potem

adc_read(1); //odczyt adc 1 - incjalizacja
if(czujnik[1] == 1)
{
//cos tam
}

Udostępnij ten post


Link to post
Share on other sites

Ale czy takiego odczytu da się użyć w jednym warunku ? Przecież dalej jest to ADCW. 😉

[ Dodano: 16-09-2012, 13:56 ]

Czy wartosć pojedynczego ADC np. ADC0 trzeba odczytywać z rejestrów MUX(x) ? W datasheecie jest taka tabelka z tymi włąśnie rejestrami i określonymi pinami ADC.

Udostępnij ten post


Link to post
Share on other sites
uint8_t a = 150; //granica
uint8_t czujnik;
uint16_t adc_read(void) {
for(int i=0; i < 0; i++) {

 ADMUX=(ADMUX & 0xf8) | i;
 ADCSRA|=(1<<ADSC);
 while(ADCSRA & (1<<ADSC));
}

if(ADCL < a) { // ADCL - Atmega16 DS str 220
czujnik = 1;
}
else{
czujnik = 0;
}


//potem

adc_read(); //odczyt adc - incjalizacja
if(czujnik == 1)
{
//cos tam
}

Udostępnij ten post


Link to post
Share on other sites
#include <avr/io.h>
#include <util/delay.h>

uint16_t adc_read(void);

int main(void){
uint8_t a = 150; //granica
uint8_t czujnik;

if(ADCL < a) { // ADCL - Atmega16 DS str 220
	czujnik = 1;
}
	else{
	czujnik=0;
}

while(1){
//potem

	adc_read(); //odczyt adc - incjalizacja
if(czujnik)
{
	PORTB=0x00;
}
 }
}

uint16_t adc_read(void){
for(int i=0; i < 0; i++) {

		ADMUX=(ADMUX & 0xf8) | i;
			ADCSRA|=(1<<ADSC);
				while(ADCSRA & (1<<ADSC));
				return  0;
}
}

Ten program się kompiluje, ale nie do końca, ponieważ wywala mi na zółto ostatni nawias - błąd :"control reaches end of non void function".

Udostępnij ten post


Link to post
Share on other sites
uint16_t adc_read(void)

zmień na

void adc_read(void)

i powinno działać.

Do pętli for wrzuć na końcu, ale nie wiem na 100% czy jest to potrzebne

return ADCL;

Udostępnij ten post


Link to post
Share on other sites
#include <avr/io.h>
#include <util/delay.h>

void adc_read(void);

int main(void){
uint8_t a = 150; //granica
uint8_t czujnik;

if(ADCL < a) { // ADCL - Atmega16 DS str 220
	czujnik = 1;
}
	else{
	czujnik=0;
}

while(1){
//potem

	adc_read(); //odczyt adc - incjalizacja
if(czujnik)
{
	PORTB=0x00;
}
 }
}

void adc_read(void){
for(int i=0; i < 0; i++) {

		ADMUX=(ADMUX & 0xf8) | i;
			ADCSRA|=(1<<ADSC);
				while(ADCSRA & (1<<ADSC));

}
}

Nie działa, ale dzięki za dobre chęci, return ADCL przecież nie może być bo funkcja jest void czyli nic nie zwraca 😉

Ciekaw tylko jestem jak z tym problemem radzą sobie inni konstruktorzy minisumo 😉

Udostępnij ten post


Link to post
Share on other sites

Napisz dokładnie co ci nie działa. Tam gdzie masz //granica masz próg przy którym ma działać np. czujnik.

Co do problemów to kombinuj ile wlezie 😉

Urywek mojego programu:


uint8_t adc6, adc5;
uint8_t czujnik= 0;
int main()
{
ADMUX |= (1<<REFS0) | (1<<REFS1); //VREF_wew 2,56V
ADCSRA |= (1<<ADEN); //Włączenie przetwornika ADC
ADCSRA |= (1<<ADPS0) | (1<<ADPS1); //Preskaler 8
{

void odczyt_adc(void) {
ADMUX &= ~(1 << 6);
ADMUX |= (1 << 6);
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));

adc6 = ADC;

ADMUX &= ~(1 << 5);
ADMUX |= (1 << 5);
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));

adc5 = ADC; //przypisanie wartości odczytu zmiennej adc5 

if(adc6 || adc5 > 300)
{
	czujnik = 1;
}
else
{
	czujnik = 0;
}
}

Udostępnij ten post


Link to post
Share on other sites

Wydaje mi się że nie działa w ogóle pomiar ADC- zawsze (przy dobrym programie) jak przed ktirkiem macham pilotem od tv z naciśniętym przyciskiem diody mrugają (i o to chodzi). A tutaj nic. Wiem że granica jest do ustawiania 😉 Jest jeszcze jedna rzecz która mnie dziwi, a mianowicie granice trzeba dostosowywać do napięcia li pola, a przecież korzystam z zewnętrznego źródła odniesienia do ADC oraz mam masę ceramików przy atmedze/na samym zasilaniu.

if(czujnik == 1)

Co do tej linijki tak nie możesz zrobić - zobacz dlaczego kompilując ten wsad 😉

PS po co jest ten for ? Bo przecież i ma zapisane 0 a potem piszesz i<0; i++ Przecież po zwiększeniu i nie będzie mniejsze od zera.

Udostępnij ten post


Link to post
Share on other sites

klonyyy, Zmodyfikowałem trochę poprzedni post - wkleiłem urywek działającego programu, nie testowałem na ktirze, ale z potencjometrem działa.

EDIT: Wartości ADC nie dostosowujesz do napięcia li-pola, tylko do (w tym przypadku) wewnętrznego VREF, czyli 2,5V (Dla większości Atmeg) - dzięki temu masz większą dokładność.

Napięcie zewnętrzne to chyba około 5V no chyba, że podłączyłeś Megę bez stabilizatora bezpośredni pod li-pola ?

Polecam przeczytać str 236 z książki nr 1 M.Kardasia.

@down - Napisałem 😅

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites
adc5 = ADC; 

Nie napisałeśco robisz w tej linijce i jako co to zdefiniowaleś 😉

[ Dodano: 18-09-2012, 07:11 ]

#include <avr/io.h>
#include <util/delay.h>


uint16_t pomiar1(uint8_t kanal1);
uint16_t pomiar(uint8_t kanal);

int main(void){

 ADMUX |= (1<<REFS0) | (1<<REFS1);
 ADCSRA |= (1<<ADEN)| (1<<ADPS1)| (1<<ADPS0);

 DDRA=0x00;

 DDRB=0xff;
 PORTB=0xff;



 while(1){

   if(pomiar(5)<=300 || pomiar1(7)<=300){
     PORTB=0x00;

   }

   if(pomiar(5)>=300 || pomiar1(7)>=300){
     PORTB=0xff;
   }

 }
}


uint16_t pomiar(uint8_t kanal){

 ADMUX=(ADMUX & 0xf8)|kanal;

 ADCSRA|=(1<<ADSC);

 while(ADCSRA & (1<<ADSC));

 return ADCW;

}
uint16_t pomiar1(uint8_t kanal1){

 ADMUX=(ADMUX & 0xf8)|kanal1;

 ADCSRA|=(1<<ADSC);

 while(ADCSRA & (1<<ADSC));

 return ADCW;

}

Działający kodzik 😉 Dzięki ps19 za pomoc !!

EDIT:

Mam do Was pytanko- może wiecie czemu dzieje się tak że jak robot się obraca i nagle zobaczy przeciwnika mimo kmendy ATAK (czyli dwa silniki do przodu) jeden silnik ( ten który obracał robotem przy obrocie) kręci się szybciej co skutkuje krzywa jazdą robota, tzn skręca w jedna stronę. Sama komenda ATAK w innym programie działa prawidłowo tzn robot jedzie równiutko po prostej. Mieliscie podobne klopoty ?

Udostępnij ten post


Link to post
Share on other sites

Możliwe, że masz coś namieszane w samym algorytmie - musisz go ułożyć tak, aby zajmował procesorowi jak najmniej czasu.

Może być tak, że dla każdego impulsu na silnik, procesor musi sprawdzać za dużo warunków i koło obraca się wolniej - program musi przelecieć sporą ilość warunków i dopiero wysyła "impuls" do mostka.

Udostępnij ten post


Link to post
Share on other sites

Hehe powiem Wam że to fajny problem był - bo mostek dostawał kopa na jedno koło, przez to że przez 1ms wuykonywał obrót, przez kolejną 1ms wykonywał atak 😉 A spowodowane to było usterką sprzętową jednego czujnika- a domyśliłem się tego dając obrót do tyłu - silni drgał, bo znowu przez 1ms był obrót (tylko że do tyłu), przez kolejną 1 ms atak ( do przodu). Niedługo premiera Hakera na you tube, ale pewnie w sobotę bo ledwo dziś czas znalazłem żeby posiedzić nad wsadem, ale jeszcze masa pracy domowej w tym rozprawka z polskiego mi została 😕

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Napisz odpowiedź...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...