Skocz do zawartości

[C] Błędna interpretacja danych z czujników


Dżony

Pomocna odpowiedź

Hej, od kilku dni siedzę i programuje starając się rozwiązać problem z kodem do mojego nowego minisumo. Mianowicie sprawa ma się tak: zrobiłem dwa osobne programy jeden tylko by sprawdzać czy czujniki działają a drugi to program główny. O to kod testowy:

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


#define IN1_A (1<<PD7)
#define IN2_A (1<<PD6)
#define IN1_B (1<<PD2)
#define IN2_B (1<<PD3)

#define SHARP1_PIN (1<<PC1)
#define SHARP2_PIN (1<<PC0)
#define SHARP3_PIN (1<<PA7)
#define SHARP4_PIN (1<<PA6)

uint8_t walka(void);
uint8_t sensors (void);
int sharp;

int main(void)
{

  DDRC=0x00;
  PORTC=0x00;
  DDRD = 0xFE;
  PORTD = 0x00;

  TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
  TCCR1B = (1<<CS10)|(1<<WGM12);

  while(1)
  {
   sensors();
   walka();
  }
}

uint8_t sensors (void)
{
sharp=0b0000;

if(!(PINC & SHARP1_PIN))
{
	sharp = 0b1000;
}
if(!(PINC & SHARP2_PIN))
{
	sharp = 0b0100;
}
if(!(PINA & SHARP3_PIN))
{
	sharp = 0b0010;
}
if(!(PINA & SHARP4_PIN))
{
	sharp = 0b0001;
}
if(!((PINC & SHARP2_PIN) &(PINA& SHARP3_PIN)))
{
	sharp = 0b0110;
}
return 0;
}
uint8_t walka(void)
{
sensors();
switch(sharp)
{
   case 0b0000:
   OCR1A = 100;
   OCR1B = 100;
   PORTD |= IN1_A;
   PORTD &= ~IN2_A;
   PORTD &= ~IN1_B;
   PORTD |= IN2_B;
   break;

   case 0b0110:
   OCR1A = 100;
   OCR1B = 100;
      PORTD &= ~IN1_A;
      PORTD |= IN2_A;
   PORTD &= ~IN1_B;
   PORTD |= IN2_B;
   break;

   case 0b1000:
   OCR1A = 100;
   OCR1B = 100;
   PORTD |= IN1_A;
   PORTD &= ~IN2_A;
   PORTD &= ~IN1_B;
   PORTD |= IN2_B;
   break;

   case 0b0001:
   OCR1A = 100;
   OCR1B = 100;
   PORTD &= ~IN1_A;
   PORTD |= IN2_A;
   PORTD |= IN1_B;
   PORTD &= ~IN2_B;
   break;

      case 0b0100:
      OCR1A = 100;
      OCR1B = 100;
      PORTD |= IN1_A;
      PORTD |= IN2_A;
      PORTD &= ~IN1_B;
      PORTD |= IN2_B;
      break;

      case 0b0010:
   OCR1A = 100;
   OCR1B = 100;
   PORTD &= ~IN1_A;
   PORTD |= IN2_A;
   PORTD |= IN1_B;
   PORTD |= IN2_B;
   break;
}
return 0;
}

Problem pojawia się gdy oba przednie czujniki mają coś widzieć razem czyli 0b0110 jak dam to w komentarz to wszystko działa poprawnie... starałem się już to na różne sposoby rozpisać ale zawsze tan sam problem: cały program i poprawne odczytywanie sygnałów z czujników znika. Sądzę że coś z tym zapisem jest nie tak:

if(!((PINC & SHARP2_PIN) &(PINA& SHARP3_PIN)))
{
	sharp = 0b0110;
}
Link do komentarza
Share on other sites

Hej,
Przy sprawdzaniu dwóch czujników instrukcją warunkową powinieneś zastosować iloczyn logiczny więc "&&". Użyłeś pojedynczy znak. Pewnie to literówka ale powoduje błąd warunku.

Hej, od kilku dni siedzę i programuje starając się rozwiązać problem z kodem do mojego nowego minisumo. Mianowicie sprawa ma się tak: zrobiłem dwa osobne programy jeden tylko by sprawdzać czy czujniki działają a drugi to program główny. O to kod testowy:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


#define IN1_A (1<<PD7)
#define IN2_A (1<<PD6)
#define IN1_B (1<<PD2)
#define IN2_B (1<<PD3)

#define SHARP1_PIN (1<<PC1)
#define SHARP2_PIN (1<<PC0)
#define SHARP3_PIN (1<<PA7)
#define SHARP4_PIN (1<<PA6)

uint8_t walka(void);
uint8_t sensors (void);
int sharp;

int main(void)
{

  DDRC=0x00;
  PORTC=0x00;
  DDRD = 0xFE;
  PORTD = 0x00;

  TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
  TCCR1B = (1<<CS10)|(1<<WGM12);

  while(1)
  {
   sensors();
   walka();
  }
}

uint8_t sensors (void)
{
sharp=0b0000;

if(!(PINC & SHARP1_PIN))
{
	sharp = 0b1000;
}
if(!(PINC & SHARP2_PIN))
{
	sharp = 0b0100;
}
if(!(PINA & SHARP3_PIN))
{
	sharp = 0b0010;
}
if(!(PINA & SHARP4_PIN))
{
	sharp = 0b0001;
}
if(!((PINC & SHARP2_PIN) &(PINA& SHARP3_PIN)))
{
	sharp = 0b0110;
}
return 0;
}
uint8_t walka(void)
{
sensors();
switch(sharp)
{
   case 0b0000:
   OCR1A = 100;
   OCR1B = 100;
   PORTD |= IN1_A;
   PORTD &= ~IN2_A;
   PORTD &= ~IN1_B;
   PORTD |= IN2_B;
   break;

   case 0b0110:
   OCR1A = 100;
   OCR1B = 100;
      PORTD &= ~IN1_A;
      PORTD |= IN2_A;
   PORTD &= ~IN1_B;
   PORTD |= IN2_B;
   break;

   case 0b1000:
   OCR1A = 100;
   OCR1B = 100;
   PORTD |= IN1_A;
   PORTD &= ~IN2_A;
   PORTD &= ~IN1_B;
   PORTD |= IN2_B;
   break;

   case 0b0001:
   OCR1A = 100;
   OCR1B = 100;
   PORTD &= ~IN1_A;
   PORTD |= IN2_A;
   PORTD |= IN1_B;
   PORTD &= ~IN2_B;
   break;

      case 0b0100:
      OCR1A = 100;
      OCR1B = 100;
      PORTD |= IN1_A;
      PORTD |= IN2_A;
      PORTD &= ~IN1_B;
      PORTD |= IN2_B;
      break;

      case 0b0010:
   OCR1A = 100;
   OCR1B = 100;
   PORTD &= ~IN1_A;
   PORTD |= IN2_A;
   PORTD |= IN1_B;
   PORTD |= IN2_B;
   break;
}
return 0;
}

Problem pojawia się gdy oba przednie czujniki mają coś widzieć razem czyli 0b0110 jak dam to w komentarz to wszystko działa poprawnie... starałem się już to na różne sposoby rozpisać ale zawsze tan sam problem: cały program i poprawne odczytywanie sygnałów z czujników znika. Sądzę że coś z tym zapisem jest nie tak:

if(!((PINC & SHARP2_PIN) &(PINA& SHARP3_PIN)))
{
	sharp = 0b0110;
}
Link do komentarza
Share on other sites

Zrobiłem tak:

if(!((PINC & SHARP2_PIN)&&(PINA & SHARP3_PIN)))
   {
        sharp = 0b0110;
   }

i teraz nie działa 0b0100 i 0b0010 🙁 wydaje się że ten warunek jest za długi i za bardzo skomplikowany.

Link do komentarza
Share on other sites

Dzieje się tak, ponieważ Twój warunek jest spełniony jeżeli którykolwiek z czujników wykryje przeszkodę.

Proponuję zmienić na:

if( !(PINC & SHARP2_PIN) && !(PINA & SHARP3_PIN) )
{ 
  sharp = 0b0110; 
} 
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Hm, nie rozumiem kilku rzeczy:

-czemu zmienna sharp ma typ int? Lepiej na uint8_t, zastosować liczby 0,2,4,8,16 itd. jak bardo chcesz mieć to pseudo-bielarnie ale nie widzę abyś potem to wykorzystywał gdzieś - funkcja switch().

-przy sprawdzaniu if ułóż warunki tak aby w danym momencie tylko jeden był prawdziwy, bardziej złożone przenieś wyżej i jeśli taki zajdzie to return-po, co sprawdzać kolejne jak i tak podpisujesz zmienną,
-dwa razy wywołujesz funkcje sensor();

-funkcje zwracają 0 ale nigdzie nie wykorzystujesz tego- zrób void.

Popraw tak i daj znać:

if((!(PINC & SHARP2_PIN)) &&(!(PINA & SHARP3_PIN))))
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Jeszcze lepiej. Program do testów działał już, ale główny nie, jak dodałem return przy każdym if to zaczął działać 😉 wielkie dzięki chłopaki! 😉

Link do komentarza
Share on other sites

grunt że działa 😋

uint8_t sensors (void)
{
sharp=0b0000;

if((!(PINC & SHARP2_PIN)) && (!(PINA & SHARP3_PIN)))
{
    return sharp = 0b0110;
}
if(!(PINC & SHARP1_PIN))
{
	return sharp = 0b1000;
}
if(!(PINC & SHARP2_PIN))
{
	return sharp = 0b0100;
}
if(!(PINA & SHARP3_PIN))
{
	return sharp = 0b0010;
}
if(!(PINA & SHARP4_PIN))
{
	return sharp = 0b0001;
}
return 0;
}

Jak co to już jutro poprawie 😉 ale dzięki

Link do komentarza
Share on other sites

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

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.