Arduino / Atmega 328 programmeer advies gevraagd.

bprosman

Golden Member

Momenteel ben ik bezig met een Arduino Mini Pro, daar mijn "programmeer skills" behoorlijk roestig zijn ben ik op zoek naar wat advies.
Ik wil een 7-Segment display rechtstreeks vanuit een Arduino mini pro aansturen voor een teller. Maar.. er is niet echt een 7..8 bits poort volledig beschikbaar. Wat is hier handig ? Ik zou er natuurlijk een BCD-7Segment decoder tussen kunnen zetten .. maar dat is wat overkill denk ik.

Hoe is dat programmeer technisch het netst op te lossen ?
(Ik kan natuurlijk een routine maken die alle bitjes los aan gaat sturen maar echt sjiek is dat niet, maar misschien de enige oplossing).
Of PC0-3 + PB0-3 ?

De jongere generatie loopt veel te vaak zijn PIC achterna.

Port C heeft 7 pennen, maar er Reset is er 1 van. Pen 4 en 5 zitten versprongen achter a2 en a3, maakt het moeilijker op expirimenteerprint.

Poort D is 8 pennen, maar bevat ook je uart.

Anders is een 74hc595 ook een optie, snel zat voor 7 segmenten.

Op ebay vind je ook veel displays met shift register.
https://www.ebay.com/itm/MAX7219-8-Digit-LED-Display-7-Segment-Digital…

GMT+1

Er is een Arduino library beschikbaar die meerdere 7 segment displays kan besturen. Behalve wat weerstanden voor de stroombegrenzing van de I/O is er geen andere hardware nodig. Zowel common Anode als common Cathode displays zijn te gebruiken.
Zie github : https://github.com/DeanIsMe/SevSeg

Gebruik een I²c expander of display met ingebouwde PCF8574

bprosman

Golden Member

74HC595, PCF8574, HEF4543/4511 had ik allemaal aan gedacht maar had gehoopt het met 1 chip (de processor) af te kunnen.
De library waar MicroDwl me naar verwijst lijkt wel te doen waar ik naar op zoek ben.
Morgen eens proberen.

De jongere generatie loopt veel te vaak zijn PIC achterna.

je hebt helemaal geen extra chip nodig.
zonde van het geld.
Je kan gewoon elke random pin van de uc gebruiken. vooral hoe het route technisch het beste uitkomt.

Op 1 poort is alleen handig omdat je dan in 1x de hele poort kan schrijven, maar dat is ook het enige.

Ik maak dan vaak een lookup tabel die de vertaling doet. Dan kan ik later als ik layout ook makkelijk iets wijzigen.
Als je je gelaagdheid in code goed maakt heb je daar op high level niks geen last om omkijken aan.
Het maakt het soms wat efficiënter om rechtstreeks pointers naar de output registers te gebruiken ipv de losse poort pinnen.
De Arduino pin nummering heeft ook geen gerelateerde logica met de echte poorten van de AVR

code:


static T_io ledIO[NR_OF_LEDS] = {
	/*1 */ { &PORTE , PORTE0},
	/*2 */ { &PORTD , PORTD4},
	/*3 */ { &PORTD , PORTD6},
	/*4 */ { &PORTD , PORTD1},			
	/*5 */ { &PORTB , PORTB0},
	/*6 */ { &PORTC , PORTC5},
	/*7 */ { &PORTB , PORTB2},
	/*8 */ { &PORTC , PORTC3},
	/*9 */ { &PORTC , PORTC1}
};

zo een tabelletje van led pin definities. Met daarin de poort en pin.
Met deze info kun je de desbetreffende pin hoog en laag maken door hem te ORen of de inverse van de pin the ANDen

code:


*ledsRed[ledIdx].pPort |= (1 << ledsRed[ledIdx].pin);

en

code:


*ledsRed[ledIdx].pPort &= ~(1 << ledsRed[ledIdx].pin);

[Bericht gewijzigd door Stijnos op donderdag 27 februari 2020 08:56:09 (32%)

bprosman

Golden Member

@Stijnos,

Daar ga ik eens mee stoeien en zal wat vertaaltabellen maken dan (denk ik) naar de 7-Segment cijfers ?

De jongere generatie loopt veel te vaak zijn PIC achterna.

deze tabel is per segment
daarna zou ik tabel maken welke segmenten je nodig hebt voor elke digit

Je kunt inderdaad elk bit apart gaat aansturen, maar dat is een dure oplossing (vergt redelijk veel code en cycles).

Efficienter is om te zoeken naar 2 groepen van naast elkaar liggende bits. Als dat uitkomt dan kun je veel sneller werken.

Bijvoorbeeld:

code:


void WriteSegments(uint8_t NewSegments)
{
   // B0..B3 into PORTC2 .. PORTC5  
   PORTC = (PORTC & 0b11000011) | ((NewSegments & 0b00001111) << 2);

   // B4..B7 into PORTD3 .. PORTD6  
   PORTD = (PORTD & 0b10000111) | ((NewSegments & 0b11110000) >> 1);
}

bprosman

Golden Member

Misschien (te) veel overhead maar dit doet precies wat ik wil.
Het moet een tellertje worden wat omhoog/omlaag telt dmv 2 toetsen.

#include <SevSeg.h>
SevSeg sevseg;

void setup() {
byte numDigits = 1;
byte digitPins[] = {};
byte segmentPins[] = {8, 9, 10, 11, 7, 6, 5, 4};
bool resistorsOnSegments = true;

byte hardwareConfig = COMMON_ANODE;
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
sevseg.setBrightness(90);

}

void loop() {
for(int i=0; i<10; i++)
{
sevseg.setNumber(i, i%2);
delay(1000);
sevseg.refreshDisplay();
}

}

De jongere generatie loopt veel te vaak zijn PIC achterna.