Skocz do zawartości

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 ?

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;

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
}

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.

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
}
#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".

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;
#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 😉

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;
}
}

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.

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
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 ?

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.

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 😕

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...