Arduino - problem z kowersja dec -> bin

void hours_set(int hours)
{
	float edit = hours;
	for (int i = 6; i >=2 ; i--)
	{
		if (edit%2)
		{
			edit = (int)(edit/2);
			digitalWrite(i, HIGH);
		} else {
			edit = (int)edit/2;
			digitalWrite(i, LOW);
		}
	}
}
void minutes_set(int minutes)
{
	float edit = minutes;
	for (int i = 12; i >=7 ; i--)
	{
		if (edit%2)
		{
			edit = (int)(edit/2);
			digitalWrite(i, HIGH);
		} else {
			edit = (int)edit/2;
			digitalWrite(i, LOW);
		}
	}
}
void setup()
{
	for (int i = 2; i <= 13; i++)
	{
		pinMode(i, OUTPUT);
	}
}
int hours = 19;
int minutes = 44;
bool clock = false;
void loop()
{
	if(hours == 24)
	{
		hours = 0;
	} else {
		hours++;
	}
	if (minutes == 59)
	{
		minutes = 0;
		hours++;
	} else {
		minutes++;
	}

	hours_set(hours);
	minutes_set(minutes);

	if (clock)
	{
		digitalWrite(13, LOW);
		clock = false;
	} else {
		digitalWrite(13, HIGH);
		clock = true;
	}
	delay(1000);
}

Montuje zegar binarny, gdzie piny od 2-6 reprezentują godzine binarnie a piny 7-12 minuty, a pin 13 tylko sekundnik. I mam problem z kodem - nie wiem co zrobić aby dobrze wyświetlał czas?

Nie mieszaj typów zmiennych. Do 24 możesz śmiało liczyć na char, nie powtarzaj instrukcji bo zapychasz pamięć procesora.

Nie ustawiaj portów po pinie.

Zakładając, że numerujesz porty zgodnie z tym obrazkiem. http://www.dominicdube.com/wp-content/uploads/Arduino-uno-Pinout.png używasz portd i portb. 

Godzinę możesz wyświetlać tak:

PIND=(hours<<2);

Oczywiście zmienna hours powinna być zmienną typu char. A wprowadzasz do niej wartość zgodnie z ogólnie przyjętą normą.

Jako że ostatnie piny w porcie D używany jest przez minutnik powinieneś do tego użyć również zmiennej dot. minut:

PIND=(hours<<2)|(minutes>>6);//przesuwasz wartość godziny w prawo, bo pierwsze 2piny zawsze są zerami, i dodajesz do tego pierwsze 2piny minut.

Minuty wyświetlasz analogicznie do godzin, z tym że musisz wyświetlić pierwsze 6 pinów i dodać sekundy

PINB=(minutes<<2)|zmienna_sekundowa_typu_bool;

Wyjścia numeruje wg nadruków na płytce.

a jak je mam ustawiać?

void hours_set(int hours)
{
	PIND=(hours<<1);
}
void minutes_set(int minutes)
{
	PINB=(minutes<<1);
}

tak?

i poprzesuwać piny z (2-12)na:

-dla godz…  (0-4)

-dla minu… (7-12)

 

**to jest to:

https://www.arduino.cc/en/Reference/PortManipulation

portd 0:7

portb nie jest w całości używany w atmegach (masz tam nawet napisane) musiałbyś sobie zmienić fusebity, ale wtedy musiałbyś mieć programator do zmiany softu w tym procesorze.

Potrzebujesz 6bitów do minut i 5bitów do godzin + sekundnik. Więc weź sobie portd jako minuty + sekundy, a portb jako godziny.

Jeśli zrobiłbyś to zgodnie z tym co napisałem, to możesz zrobić tak:

PINB=hours;//ustawisz 5ostatnich pinów portub jako stan godziny więc to z nich powinieneś korzystać

PIND=(minutes1)|sekundy;//(przesuwasz minuty 1bit w lewo, a na ostatni bit dodajesz sekundy), używasz wtedy ostatnich 7bitów portud, możesz przesunąć całość o 2bity i wtedy będziesz używał pierwszych pinów (ostatni pin będzie wolny)

A co do pytania w tytule, to kompilator zmieni liczbę dziesiętną na binarną. Więc jeśli nie wpisujesz niczego z zewnątrz to nie musisz nic konwertować.

void hours_set(int hours)
{
	PIND=(hours<<1);
}
void minutes_set(int minutes)
{
	PINB=(minutes<<1);
}
void setup()
{
	for (int i = 0; i <= 13; i++)
	{
		pinMode(i, OUTPUT);
	}
}
int hours = 19;
int minutes = 44;
bool clock = false;
void loop()
{
	if(hours == 24)
	{
		hours = 0;
	}
	if (minutes == 59)
	{
		minutes = 0;
		hours++;
	} else {
		delay(1000);
		minutes++;
	}
	hours_set(hours);
	minutes_set(minutes);
}

Aktualnie mam:

piny 0-4 dla godz (5bit)

a piny 7-12 dla minut (6bit)

 

i teraz jak mam to wyprowadzic na prostą?

Jeśli używasz starszych pinów musisz przesunąć wartość bardziej w ich kierunku, jednak zgodnie z linkiem który podałeś nie powinieneś używać dwóch najstarszych pinów portub (a ty używasz jednego z nich). Używanie funkcji dla jednej instrukcji mija się z celem.

void setup()
{
    DDRD=0xFF;//portd jako wyjście
    DDRB=0xFF;//portb jako wyjście
}
char hours = 19;
char minutes = 44;
bool clock = false;
void loop()
{
	if(hours == 24)
	{
		hours = 0;
	}
	if (minutes == 59)
	{
		minutes = 0;
		hours++;
	} else {
		minutes++;
		clock=~clock;//zmiana stanu clock co sekundę
	}
	delay(1000);//zajęcie procesora poza warunkiem (bo ci będzie przeskakiwał o sekundę co 24h i co godzinę)
	//weź poprawkę że delay działa względem ustawionej w kompilatorze częstotliwości pracy procesora
	PORTB=(hours<<2);
	PORTD=(minutes<<1)||sekundy;
}

piny 9:13 to godzina, a piny 1:6minuty, a 7pin to sekundnik. Pisane z palca, ale powinno działać.

Weź też pod uwagę, że użycie delay spowoduje że nie zrobisz z procesorem nic innego. Powinieneś zacząć korzystać z przerwań.

void setup()
{
    DDRD=0xFF;//portd jako wyjście
    DDRB=0xFF;//portb jako wyjście
}
int hours = 22;
int minutes = 14;
int seconds = 0;
bool clock = false;
void loop()
{
	if(hours == 24)
	{
		hours = 0;
	}
	if (minutes == 59)
	{
		minutes = 0;
		hours++;
	}
	if(seconds == 59)
	{
		seconds = 0;
		minutes++;
	} else {
		seconds++;
		delay(910);
	}
	
	PORTB=(hours<<2);
	PIND=(minutes<<1)||seconds;
}

Porty 9:13 to godzina, a porty 1:6minuty, a 7port to sekundnik

 

tak?

Wszystko ma mieć typ char, a co do sekund nie. Musiałbyś usunąć wszystkie bity poza ostatnim.

=(minutes<<1)|(seconds&1);

Poza tym delay musisz mieć poza if, bo ci będą przeskakiwać stany po wykonaniu if’a będziesz miał 2 przejścia a nie jedno. W sumie jeden kij.

void setup()
{
    DDRD=0xFF;//portd jako wyjście
    DDRB=0xFF;//portb jako wyjście
}
char hours = 22;
char minutes = 27;
int seconds = 0;
bool clock = false;
void loop()
{
	if(hours == 24)
	{
		hours = 0;
	}
	if (minutes == 59)
	{
		minutes = 0;
		hours++;
	}
	if(seconds == 59)
	{
		seconds = 0;
		minutes++;
	} else {
		seconds++;
		delay(980);
	}
	
	PORTB=(hours<<2);
	PIND=(minutes<<1)||(seconds&&1);
}

wszystko char, poza sekundami

 

minuty wogole sie nie świeca a sa dobrze polaczone

Już zdążyłem poprawić, ma być & a nie && (ten drugi daje stan logiczny a nie and) or analogicznie 

A sekundy też mają być char.

void setup()
{
    DDRD=0xFF;
    DDRB=0xFF;
}
char hours = 10;
char minutes = 0;
char seconds = 0;
void loop()
{
    if(seconds == 59)
    {
        seconds = 0;
        minutes++;
    } else {
        seconds++;
        delay(980);
    }
    if (minutes == 59)
    {
        minutes = 0;
        hours++;
    }
    if(hours == 24)
    {
        hours = 0;
    }
    PORTB=(hours<<2);
    PIND=(minutes<<1)|(seconds&1);
}

stan wyjsc dla godziny sie zgadza 9 = 01001, ale minuty nie koniecznie bo przeskaują po miedzy stanami: 100000 a 001101 suma obydwóch to 45 sie zgadza, ale nie da się w jednym cyklu?

a dla 10.00 juz sie nie zgadza bo 00101 a minuty 100000

zegar dziala nie prawidlowo?

delay(980) nie da ci jednej sekundy

przeskakiwanie tej sumy to raczej wina optymalizacji kompilatora - dołóż nawias albo zmienną tymczasową.

PORTD=((minutes<<1)|(seconds&1));

Albo (jeśli pierwsze nie zadziała):

char tmp=((minutes<<1)|(seconds&1));
PORTD=tmp;

a co do złego stanu ma być portb a nie pinb, zdebugowałem ten kod i działa tak jak powinien.

Kod do Arduino:

void setup()
{
    DDRD=0xFF;
    DDRB=0xFF;
}
char hours = 12;
char minutes = 33;
char seconds = 0;
void loop()
{
	if(seconds == 59)
	{
		seconds = 0;
		minutes++;
	} else {
		seconds++;
		delay(1000);
	}
	if (minutes == 59)
	{
		minutes = 0;
		hours++;
	}
	if(hours == 24)
	{
		hours = 0;
	}
	PORTB = (hours<<2);
	PORTD = ((minutes<<1)|(seconds&1));
}

Używane PINy:

godzina: 8-13

minuty: 1-6

 

Zamiast 12:30, pokazuje 00011(H) i 110001(M), metoda z PORTD/B nie działa?

 

Nie było by łatwiej wykorzystać bit po bicie?

void hours_set(int hours)
{
	float edit = hours;
	for (int i = 6; i >=2 ; i--)
	{
		if (edit%2)
		{
			edit = (int)(edit/2);
			digitalWrite(i, HIGH);
		} else {
			edit = (int)edit/2;
			digitalWrite(i, LOW);
		}
	}
}
void minutes_set(int minutes)
{
	float edit = minutes;
	for (int i = 12; i >=7 ; i--)
	{
		if (edit%2)
		{
			edit = (int)(edit/2);
			digitalWrite(i, HIGH);
		} else {
			edit = (int)edit/2;
			digitalWrite(i, LOW);
		}
	}
}

 

Spróbuj tak (zadeklaruj wcześniej zmienne):

tam gdzie masz sekundy itd zadeklarowane daj:

void setup()
{
    DDRD=0xFF;
    DDRB=0xFF;
    pinMode(7, OUTPUT);
}
char hours = 13;
char minutes = 14;
char seconds = 6;
bool clock = false;
volatile char TMPB;
volatile char TMPD
void loop()
{
	if(seconds == 59)
	{
		seconds = 0;
		minutes++;
	} else {
		seconds++;
		delay(1000);
	}
	if (minutes == 59)
	{
		minutes = 0;
		hours++;
	}
	if(hours == 24)
	{
		hours = 0;
	}
	TMPB = (hours<<2);
    PORTB = TMPB;
    TMPD = (minutes<<1)|(seconds&1);
    PORTD = TMPD;
	if (clock)
	{
		digitalWrite(7, LOW);
		clock = false;
	} else {
		digitalWrite(7, HIGH);
		clock = true;
	}
}

i mam:

sketch_dec13a.ino:4:1: error: expected initializer before ‘void’
sketch_dec13a.ino:13:1: error: expected initializer before ‘void’

 

ta migająca dioda jest najmłodszym pinem z minut więc ten  if na końcu jest zbędny. Wartości zmiennych powinieneś przypisywać w setup. A jeśli przeniesienie tego do tej funkcji nie zadziała to powinieneś wywalić to volatile, widać kompilator do arduino nie wie co to.

btw połknąłeś linie kopiując

Jak dałem do setupa:

void setup()
{
    DDRD=0xFF;
    DDRB=0xFF;
    pinMode(7, OUTPUT);
    char hours = 13;
	char minutes = 14;
	char seconds = 6;
	bool clock = false;
	volatile char TMPB;
	volatile char TMPD;
}
void loop()
{
	if(seconds == 59)
	{
		seconds = 0;
		minutes++;
	} else {
		seconds++;
		delay(1000);
	}
	if (minutes == 59)
	{
		minutes = 0;
		hours++;
	}
	if(hours == 24)
	{
		hours = 0;
	}
	TMPB = (hours<<2);
    PORTB = TMPB;
    TMPD = (minutes<<1)|(seconds&1);
    PORTD = TMPD;
	if (clock)
	{
		digitalWrite(7, LOW);
		clock = false;
	} else {
		digitalWrite(7, HIGH);
		clock = true;
	}
}

To wywaliło:

sketch_dec13a.ino: In function ‘void loop()’:
sketch_dec13a.ino:15:5: error: ‘seconds’ was not declared in this scope
sketch_dec13a.ino:18:3: error: ‘minutes’ was not declared in this scope
sketch_dec13a.ino:23:6: error: ‘minutes’ was not declared in this scope
sketch_dec13a.ino:26:3: error: ‘hours’ was not declared in this scope
sketch_dec13a.ino:28:5: error: ‘hours’ was not declared in this scope
sketch_dec13a.ino:32:2: error: ‘TMPB’ was not declared in this scope
sketch_dec13a.ino:32:10: error: ‘hours’ was not declared in this scope
sketch_dec13a.ino:34:5: error: ‘TMPD’ was not declared in this scope
sketch_dec13a.ino:34:13: error: ‘minutes’ was not declared in this scope
sketch_dec13a.ino:34:26: error: ‘seconds’ was not declared in this scope
sketch_dec13a.ino:36:6: error: ‘clock’ was not declared in this scope

a jak wyjąłem z setupa:

void setup()
{
    DDRD=0xFF;
    DDRB=0xFF;
    pinMode(7, OUTPUT);
}
char hours = 13;
char minutes = 14;
char seconds = 6;
bool clock = false;
volatile char TMPB;
volatile char TMPD;
void loop()
{
	if(seconds == 59)
	{
		seconds = 0;
		minutes++;
	} else {
		seconds++;
		delay(1000);
	}
	if (minutes == 59)
	{
		minutes = 0;
		hours++;
	}
	if(hours == 24)
	{
		hours = 0;
	}
	TMPB = (hours<<2);
    PORTB = TMPB;
    TMPD = (minutes<<1)|(seconds&1);
    PORTD = TMPD;
	if (clock)
	{
		digitalWrite(7, LOW);
		clock = false;
	} else {
		digitalWrite(7, HIGH);
		clock = true;
	}
}

to nie wywala żadnych błedów, lecz diody pokazują błedny czas…