hallo beste co'ers,
ik heb net mijn arduino binnen, en nu een LED cube gemaakt. Omdat de arduino uno maar 13 poorten heeft heb ik de kubus gecharlieplext. om dit te laten werken moeten de arduino poorten als ground en +5v kunnen dienen, en dit is ook mogelijk door de poort op low te zetten. Het probleem is dat de poorten als ze ongebruikt zijn op "low" staan, dus automatisch als een ground dienen, hierdoor gaan leds die helemaal niet moeten branden wel branden. heeft iemand hier een oplossing voor? inbegrepen in de code of door een component er tussen te zetten?

Een pin op hi-Z zetten. Een pin is een charlie-lijn.

http://upload.wikimedia.org/wikipedia/commons/9/99/3_Pin_Charlieplexing.png

Dus op input zetten (DDRx.y=0) en Pull-up uit (PORTx.y=0).

@ lucky luke, wat bedoel je, ik snap het niet?
@res mijn kubus is al gebouwt, en ik wil graag intern zo min mogelijk aanpassen.

Pin als input zetten zonder pull-up als 'ie ongebruikt is; dan zweeft 'ie...

Als klopt wat je zegt (charlieplexing), dan heb je het schema gemaakt wat RES heeft gepost. (zeer waarschijnlijk met meer dan drie pins). :-)

Als je led6 aan wil hebben, moet pin1 hoog, pin2 HighZ, pin3 laag.


LEDS_PIN1_OUTPUT (); LEDS_PIN1_HI ();
LEDS_PIN2_INPUT ();
LEDS_PIN3_OUTPUT (); LEDS_PIN3_LO ();

(ik heb dan ergens een macro die zegt dat LEDS_PIN1_OUTPUT betekent:


   DDRB |= _BV (PB1);

(als pin B1 dus die LEDS_PIN1 moet voorstellen).
Dat "zonder pullup" ben ik even overheen gegaan. Er zou dan een led ergens zo zwak branden dat je hem waarschijnlijk niet eens ziet. Maar goed, anders moet er op de tweede regel nog een LEDS_PIN2_LO (); bij....

@rew, dus als ik je goed begrijp zet je met de command die je gepost hebt de pin in een "zwevende stand, dat hij gewoon dicht staat en geen + of - is?

Op 4 november 2011 08:14:36 schreef Murmeltier:
dat hij gewoon dicht staat en geen + of - is?

Beter gezegd: dat hij gewoon open staat.

Als zo'n pin als ingang zonder pull-up staat loopt er "geen" stroom in of uit. (Zodanig verwaarloosbaar weinig). Er is dus geen verbinding met de + of - voeding, dat noemen we dus "open". Een open ciruit. Als er wel een verbinding is heet het "gesloten".

Vergelijk het maar met een open brug ipv. een gesloten kraan.

oke, ik snap het, en hoe krijg ik dit voor elkaar met de arduino? ik heb tussen de uitgang en de kubus per uitgang een weerstand van 100Ω staan? is dit dan (perongeluk) een pull-up weerstand?

ik heb gelezen dat een pull-up resistor meestal 10KΩis, maar kunnen de 100Ω weerstanden ook perongeluk als pull up weerstand dienen? helpt het dan om die weg te halen?

Nee, dat zijn serieweerstanden, en die heb je bij LED's wel degelijk nodig.

Pull-up zit in de avr zelf. Je hebt voor zo'n uitganspin 4 mogelijkheden:

- Hij is uitgang, en hoog (5V)
- Hij is uitgang, en laag (0V)
- Hij is ingang, met pull-up (5V)
- Hij is ingang, zonder pull-up (zweeft)

In de AVR zitten voor de i/o per poort 3 registers. DDRx, PORTx en PINx. Dus voor poort A: DDRA, PORTA en PINA. (In de arduino-omgeving kun je die namen als het goed is ook gewoon gebruiken, dat is dan efficienter dan PinMode en DigitalWrite)

DDRx is het Data Direction Register. Staat er een 1 in, dan is dat pinnetje een Uitgang, staat er een 0 dan is het een Ingang. (Dus is bitje 3 van DDRA een 1, dan is porta.3 een uitgang.)

PORTx kun je op 2 manieren gebruiken. Staat een pin als ingang, dan kun je het bijbehorende bitje in PORTx hoog te maken de pull-up aanzetten. Maak je het bitje laag staat de pull-up uit. Staat de pin als uitgang, dan kun je door het bijbehorende bitje in PORTx te zetten de uitgang hoog maken. Maak je het bitje 0 is de uitgang ook laag.

PINx gebruik je vervolgens om uit te lezen wat de waarde is die op de port staat. Is een pin hoog dan is het bijbehorende bitje in PINx 1, is die laag dan staat er een 0.

Als je dus van uitgang laag naar ingang met pull-up wilt moet je opletten: eerst DDR aanpassen, dan PORT. (Anders heb je tijdelijk een uitgang hoog, en dat kan afhankelijk van wat er aan die uitgang hangt nogal ongewenst zijn).

Enfin. Je zet met PinMode je pin als input en vervolgens digitalWrite je 'm laag. Of efficiënter door direct DDRX en dan PORTx aan te passen.

Op 5 november 2011 21:45:37 schreef Lucky Luke:
- Hij is uitgang, en hoog (5V)
- Hij is uitgang, en laag (0V)
- Hij is ingang, met pull-up (5V)
- Hij is ingang, zonder pull-up (zweeft)

En... als je het datasheet goed leest... als ie hoog (5V) moet zijn, en je gaat stroom trekken dan zakt de spanning iets. bij 1mA 25mV. Bij 10mA 250mV. Bij 40mA 1V. Veel verder moet je volgens Atmel niet gaan. In ieder geval gedraagt de output zich als een 25 ohm weerstand in serie met een spannings bron van 5V.

Bij laag geldt hetzelfde verhaal. Weer 25 ohm. (die weerstand wordt ongeveer 30 ohm als je de CPU met maar 3.3V voedt).

Bij "ingang met pull-up" is de weerstand ongeveer 60k geloof ik. Dat is van belang als je de pullup nodig hebt, maar bijna altijd de output laag trekt. Als je dan de belasting op je batterij wilt weten, moet je rekenen met die 60k weerstand.

Als ie puur ingang moet zijn, is de stroom maximaal 5 micro ampere geloof ik. Of mischien zelfs maximaal 1 microampere. Dat komt dus neer op een weerstand van minimaal 1 Mohm. (mischien zelfs 5 MOhm).

Vooral die laatste zal een "worst case" getal zijn. In de praktijk zal het me verbazen als er meer dan een tiende van die stroom gaat lopen (bij 25 graden).

Op 5 november 2011 21:45:37 schreef Lucky Luke:
Enfin. Je zet met PinMode je pin als input en vervolgens digitalWrite je 'm laag. Of efficiënter door direct DDRX en dan PORTx aan te passen.

dus, als ik je goed begrijp moet ik in de setup

void setup 
pinMode(13, INPUT);

zetten en in de loop

void loop
pinMode(13, LOW);

als ik hem zwevend wil en als ik hem "aan" wil

pinMode(13, HIGH);

deze code.
en als ik hem dan als -pool wil laten dienen, moet ik dan via pinmode de pin veranderen van input naar output?

Bijna

Hoog:


pinMode(ledPin, OUTPUT);   //Output
digitalWrite(ledPin, HIGH) //Hoog

Laag:


pinMode(ledPin, OUTPUT);   //Output
digitalWrite(ledPin, LOW) //Laag

Zwevend


pinMode(ledPin, INPUT)   //Input
digitalWrite(ledPin, LOW) //Zwevend maken (pullup uit)

Eventueel moet je deze functies zelf schrijven door de juiste regsiters direct aan te spreken. De arduino opdrachten zijn veeeel langzamer dan direct aansturen. Dus ik zou eerst kijken of dit werkt en dan kijken welke registers je op welke manier moet aansturen.

Op 6 november 2011 09:24:58 schreef pientertje:
Bijna

Hoog:


pinMode(ledPin, OUTPUT);   //Output
digitalWrite(ledPin, HIGH) //Hoog

Laag:


pinMode(ledPin, OUTPUT);   //Output
digitalWrite(ledPin, LOW) //Laag

Zwevend


pinMode(ledPin, INPUT)   //Input
digitalWrite(ledPin, LOW) //Zwevend maken (pullup uit)

Eventueel moet je deze functies zelf schrijven door de juiste regsiters direct aan te spreken. De arduino opdrachten zijn veeeel langzamer dan direct aansturen. Dus ik zou eerst kijken of dit werkt en dan kijken welke registers je op welke manier moet aansturen.

oke, dus zo, en dan de pins pas in de loop aanzetten? of toch toeschrijven in de setup, maar "tussendoor" veranderen?

Hartstikke bedankt circuitsonline, ik snap het idee en het werkt, in show your projects zal ik wel een paar fotos/filmpjes laten zien