U-Disp - The Digg (tm) display (Open Source) (16 / 18 stap)

Stap 16: De beschrijving van het Project - Firmware

De firmware is geschreven in AVR-GCC en ongeveer 60% van de beschikbare programma ruimte van 2KB in de ATtiny2313 gebruikt.

Het is eigenlijk heel simpel stuk van software. In principe controleren alles wat het doet om te ontvangen van opdracht pakketten op de seriële poort van de Tiny2313, of de opdracht is voor deze weergave, en als het decoderen van de opdracht en de bitpattern in het geheugen opslaan. Als de opdracht is voor een ander scherm die het zal gewoon doorgeven aan de volgende weergave.
De firmware kan downloaden, zowel als broncode en als vooraf gecompileerde hexfile van de downloadsectie van de website van het project.

De berichten tussen de Windows-Service en de microcontrollers op de displays zijn opgemaakt in vrij compacte 10 byte pakketten. Om te kunnen op betrouwbare wijze het detecteren van het begin van elk pakje de meest significante bit [MSB] (bit 7 thats) in de eerste byte is ingesteld op nul, de rest van de bytes zijn ingesteld op één.

Aangezien elk cijfer heeft acht LED's (de zeven segmenten plus het decimaalteken [DP]) die moet worden gecontroleerd toewijzen niet wij gewoon elk cijfer op één byte, omdat dat de MSB ingesteld krijgen zou op nul (het begin van packet indicator) als het decimaalteken was uitgeschakeld. Dus de DPs krijgt eigen byte, maar aangezien we acht cijfers, en dus acht DPs hebben de laatste DP moet komen krijgen ergens anders of we in het zelfde probleem opnieuw. De laatste cijfers DP wordt gelegd op de eerste byte bij beetje zes...

De eerste byte is naast de signalering van de packet start en houden van de laatste cijfers DP heeft ook vier stukjes (bit 3-0) die aangeeft welke weergave (eenheid), dit bericht is voor. De eerste display is genummerd 0 de volgende 1 en de laatste weergave is nummer 15. Wanneer het eerste scherm in een keten ontvangt een bericht dat het controleert de unit number/logisch en ziet als het is 0. Als dat het bericht er is verwerkt. Het is dan niet de weergave verlaagd de waarde in de eenheid bits als het volledige bericht langs wordt doorgegeven aan de volgende weergave in de keten. Dat display ook de bits voor nul controleert en dienovereenkomstig handelt.

 Bit no | 7 6 5 4 3 2 1 0-------+---------------------------------------------Byte 0 | 0 d7p x x u3 u2 u1 u0 1 | 1 G F E D C B A (digit 0) 2 | 1 G F E D C B A (digit 1) 3 | 1 G F E D C B A (digit 2) 4 | 1 G F E D C B A (digit 3) 5 | 1 G F E D C B A (digit 4) 6 | 1 G F E D C B A (digit 5) 7 | 1 G F E D C B A (digit 6) 8 | 1 G F E D C B A (digit 7) 9 | 1 d6p d5p d4p d3p d2p d1p d0p 

De bovenstaande tabel ziet u de indeling van het bericht.

  • d0p is het cijfer 0 decimaalteken, d1p is de Digit1 decimale komma, enzovoort...
  • U0, u1, u2, u3 zijn de stukjes die vertelt de unit number/logisch dat het bericht bestemd is.
  • A, B, C, D, E, F, G zijn de segmenten van elk cijfer.
  • x is een ongebruikte bit voor toekomstige uitbreidingen.

Opdracht ontvangen
Ontvangst van de gegevens van de PC wordt gedaan met interrupts. Elk binnenkomend teken generats een interrupt en wordt verwerkt door de functie hieronder. Het verzamelt tien tekens in een buffer, wordt gecontroleerd als de opdracht voor deze weergave en het decodeert en als het is opgeslagen. Als het bericht voor een ander weer verlaagt de bestemming nybble en verzenden het gehele bericht naar de volgende weergave in de keten in de hoop dat een display later zullen er zijn om het bericht.

 //// This is the interrupt handler for the UART data received.//// Collect all incomming characters in the rxBuf -buffer until// we got all ten charachets of the message// Then check if the message is for this unit. If it is, decode the// data and put it in the display array. Othervise pass it on to the// next display in the chain.//ISR(SIG_USART0_RX) { unsigned char rx; rx = UDR; // Get the incomming data // If the MSB if the character is not set then it's a start byte if (rx < 128) { rxPtr = 0; // So reset the buffer pointer to zero } rxBuf[rxPtr++] = rx; // Store the character in the buffer // If we got the entire message then process it. if (rxPtr == MSG_LENGTH) { // Check If the message is for us if ((rxBuf[0] & 0x0F)== 0) { // Yes, decode and store in memory for (rx=0; rx<8; rx++) { digits[rx] = (rxBuf[rx+1] & 0x7F); } if (bit_is_set(rxBuf[0],6)) digits[7] |= 0x80; for (rx=0; rx<7; rx++) { if (bit_is_set(rxBuf[MSG_LENGTH-1],rx)) digits[rx] |= 0x80; } } else { // Not for us, so we just pass it on rxBuf[0]--; // Decrement the unit-counter // Copy the entire message to the transmit buffer for (int i=0; i txBuf[i] = rxBuf[i]; } txPtr = 1; // The next character to be sent by the ISR UDR = txBuf[0]; // Send the first character manually to trigger the ISR } rxPtr = 0; // Reset the receive buffer pointer to zero } // Make sure that the pointer can't point outside the buffer if (rxPtr >= MSG_LENGTH) rxPtr = MSG_LENGTH - 1;} 

Cijfer multiplexing
Aangezien de cijfers zijn multiplexed (slechts één van de cijfers worden aangedreven tegelijk) de firmware continu brandt cijfers na cijfers voor een paar milliseconden in zodat de oog/hersenen is van mening dat alle cijfers op hetzelfde moment, op zijn.

Als u wilt opslaan van I/O-pinnen op de microcontroller een speciale multiplexing techniek genaamd Charlieplexing wordt gebruikt. Het drastisch vermindert het aantal benodigde pennen van de microcontroller maar vereist een meer complexe software onder controle.

Timer0 wordt gebruikt voor het genereren van interrupts voor de cijfers multiplexing

 // Define the i/o pins that are connected to the charlieplexed// display. The suffix B or D makes it easier to keep track// of the PORT the bit belongs to.#define CHARLIE_1_B PB3#define CHARLIE_2_B PB1#define CHARLIE_3_D PD5#define CHARLIE_4_D PD3#define CHARLIE_5_D PD4#define CHARLIE_6_B PB0#define CHARLIE_7_B PB4#define CHARLIE_8_B PB2#define CHARLIE_9_D PD6uint8_t digits[8]; // The array containing the digits to be shown on the display//// This is the Interrupt Service Routine that need to get called // often enough to not show any visible flickering on the displays.//ISR (SIG_OVERFLOW0) { static uint8_t currentdigit=0; // Keeps track of the digit to be shown uint8_t segments; // The bitpattern of the current digit TCNT0 = 128; // Reset TCNT0 halfway to get a higher freq // Get the bit pattern of the current digit segments=digits[currentdigit]; // Set all LED-portpins as inputs so the corresponding // segments of the displays will be off DDRB &= ~( _BV(CHARLIE_1_B) | _BV(CHARLIE_2_B) | _BV(CHARLIE_6_B) | _BV(CHARLIE_7_B) | _BV(CHARLIE_8_B) ); DDRD &= ~( _BV(CHARLIE_3_D) | _BV(CHARLIE_4_D) | _BV(CHARLIE_5_D) | _BV(CHARLIE_9_D) ); // Set low level on all LED-port pins. This prepares the segments // to be lit if the pin is changed to output at a later stage. The // displays ar of common anode-type (common positive) so the segments // needs to be sunk to ground to be turned on. PORTB &= ~( _BV(CHARLIE_1_B) | _BV(CHARLIE_2_B) | _BV(CHARLIE_6_B) | _BV(CHARLIE_7_B) | _BV(CHARLIE_8_B) ); PORTD &= ~( _BV(CHARLIE_9_D) | _BV(CHARLIE_3_D) | _BV(CHARLIE_4_D) | _BV(CHARLIE_5_D) ); // Set portpins as output for segments to be lit // We just assume that each segment has it's standard // place in the connections. The special case is handled // in the switch-statement below. if (bit_is_set(segments,0)) DDRB |= _BV(CHARLIE_1_B); if (bit_is_set(segments,1)) DDRB |= _BV(CHARLIE_2_B); if (bit_is_set(segments,2)) DDRD |= _BV(CHARLIE_3_D); if (bit_is_set(segments,3)) DDRD |= _BV(CHARLIE_4_D); if (bit_is_set(segments,4)) DDRD |= _BV(CHARLIE_5_D); if (bit_is_set(segments,5)) DDRB |= _BV(CHARLIE_6_B); if (bit_is_set(segments,6)) DDRB |= _BV(CHARLIE_7_B); if (bit_is_set(segments,7)) DDRB |= _BV(CHARLIE_8_B); // Here we do the bit-fiddling thats neccesary to charlieplex. // Since one of the segments (each different) of each display // is moved to the 9'th connection we need to take care of that. // // Depending on which digit that are active now we need to handle // the situation in its own unique way. // // The A segment on the first digit is moved from the 1'th line // to the 9'th line so be basically to the same thing as in the bunch // of tests above, but only test for the A segment and if it's lit // we turn on the 9'th line instead of the first line. // We then need to activate the transistor that handles the common // anode for the first digit. The transistor for the first display // is connected to the 1'th line (where the A-segment usualy go). // so we turn on the output for that pin and set it high. // // The next time this routine is called we do the same thing with // the second digit. But we then check for the B-segment and so on... switch (currentdigit) { case 0: if (segments & 0b00000001) DDRD |= _BV(CHARLIE_9_D); DDRB |= _BV(CHARLIE_1_B); PORTB |= _BV(CHARLIE_1_B); break; case 1: if (segments & 0b00000010) DDRD |= _BV(CHARLIE_9_D); DDRB |= _BV(CHARLIE_2_B); PORTB |= _BV(CHARLIE_2_B); break; case 2: if (segments & 0b00000100) DDRD |= _BV(CHARLIE_9_D); DDRD |= _BV(CHARLIE_3_D); PORTD |= _BV(CHARLIE_3_D); break; case 3: if (segments & 0b00001000) DDRD |= _BV(CHARLIE_9_D); DDRD |= _BV(CHARLIE_4_D); PORTD |= _BV(CHARLIE_4_D); break; case 4: if (segments & 0b00010000) DDRD |= _BV(CHARLIE_9_D); DDRD |= _BV(CHARLIE_5_D); PORTD |= _BV(CHARLIE_5_D); break; case 5: if (segments & 0b00100000) DDRD |= _BV(CHARLIE_9_D); DDRB |= _BV(CHARLIE_6_B); PORTB |= _BV(CHARLIE_6_B); break; case 6: if (segments & 0b01000000) DDRD |= _BV(CHARLIE_9_D); DDRB |= _BV(CHARLIE_7_B); PORTB |= _BV(CHARLIE_7_B); break; case 7: if (segments & 0b10000000) DDRD |= _BV(CHARLIE_9_D); DDRB |= _BV(CHARLIE_8_B); PORTB |= _BV(CHARLIE_8_B); break; } // Show next digit at the next interrupt. This can't be done // at the top of the ISR since the digit variable is needed // in the switch-statement later on. currentdigit++; if (currentdigit>7) currentdigit=0;} 

Gerelateerde Artikelen

Open Source TV Box - GeekBox

Open Source TV Box - GeekBox

"... u bent een slaaf, Neo. Net als iedereen je geboren tot knechtschap. In een gevangenis die u niet kan proeven of zien of aanraken. Een gevangenis voor je geest." Morpheus - The Matrix (1999)OK. Ik moet toegeven dat is een theatrale introduct
Open Source 3D gedrukte waterfilter

Open Source 3D gedrukte waterfilter

Faircap het doel is om te zorgen voor schoon water voor iedereen, in die geest we kómen filtratie-hulpprogramma's die verwijderen van bacteriën en virussen. Ons doel is het maken van een waterfilter van $1, hopen we te lopen een crowdfunding-campagne
ZelosLaser Cutter 2.0: Open Source, stevige & veelzijdige

ZelosLaser Cutter 2.0: Open Source, stevige & veelzijdige

Ik begin te plannen van de graveur ZelosLaser met als doel een goedgebouwde, Open Soft- en Hardware Machine.The ZelosLaser graveur is betaalbaar, met een compact ontwerp en het perfecte item voor de dagelijkse Hobbyist.Het is gemakkelijk om te bouwen
Open-Source 3D afgedrukt Couture door XYZ Workshop

Open-Source 3D afgedrukt Couture door XYZ Workshop

Op augustus 19, 2014, XYZ Workshop partnered met Ultimaker vrij te geven van een opensource mode suite waarin een 3D afgedrukt portemonnee, 3D afgedrukt horloge band en en hele couture jurk genaamd de inBloom jurk. Deze ontwerpen zijn allemaal gratis
WORD LID VAN ONZE OPEN SOURCE ELEMENT JURK!

WORD LID VAN ONZE OPEN SOURCE ELEMENT JURK!

Laten we beginnen een ontwerp-RIOT!DE OPEN SOURCE-JURK.Wij de uitvinder van een jurk die is gemaakt door niemand van ons, in plaats daarvan - gemaakt met THE WORLD. Met u! Door het indienen van uw eigen element voor ons allemaal samen in één jurk wor
DIY Open-Source Plug-in hybride pick-up Truck

DIY Open-Source Plug-in hybride pick-up Truck

mijn naam is Ben Nelson.Mijn voorstel voor de Jack Daniels onafhankelijkheid Project is een D.I.Y., Open-Source, Bio-brandstof-Electric Plug-in hybride pick-up truck.Oef, dat is een mondvol - tot nu toe, ik heb net al noemde het de "Super TRUCK"
Getto Pixels - bouwen van een open source BlinkM

Getto Pixels - bouwen van een open source BlinkM

tenzij je hebt geleefd onder een digitale rots voor de laatste paar jaar, of gewoon zijn niet geïnteresseerd in het knipperende lichten, u zult al genoeg weten over de awesomeness dat is de BlinkM van ThingM. Het is een zeer kleine PCB met een hoogve
Bukobot 3D Printer - Open Source, uitbreidbare

Bukobot 3D Printer - Open Source, uitbreidbare

Buko is mijn idee van een nieuw kader voor de volgende generatie van RepRap 3D Printers. 3D printers met behulp van dit kader worden Bukobots genoemd.-Eenvoudig te bouwen-Eenvoudig uitbreiden of bijwerken-Dual Extruder optie!-Geweldige documentatie-O
Fenrir: Een Open source hond robot

Fenrir: Een Open source hond robot

Stationaire been bewegingRotatie transformatieWandelen DemoDe gebruikersinterfaceDit is een mini opensource zoogdier viervoeter robot, of u kunt denken aan het als robot hond vier been. Het doel van dit project is dat mensen de mogelijkheid te creëre
Open Source CNC Toolpathing werkstroom

Open Source CNC Toolpathing werkstroom

een overzicht van gratis en open-source toolpathing voor de DIYLILCNC (of een 3-assige CNC). Een rasterafbeelding omzetten in een G-Code gravure patroon met EMC2 in Ubuntu, GIMP, Inkscape en Pycam.
Open Source 2d Cutter

Open Source 2d Cutter

Objecten afdrukken vanaf computers houdt de belofte van de productie wordt verlegd naar de hoek slaan-- of uw garage.  Hedendaagse 3D-printers en laser snijplotters zijn geweldig, maar duur.  Om een versnelling van de uitvoering van deze vorm van tec
De DIYLILCNC: Open-Source plannen voor een Low-Cost, gemakkelijk-aan-bouwstijl CNC Mill. (v1.0.2)

De DIYLILCNC: Open-Source plannen voor een Low-Cost, gemakkelijk-aan-bouwstijl CNC Mill. (v1.0.2)

Het DIYLILCNC -project is een reeks van plannen voor een goedkope, volledig functionele 3-axis CNC mill die kunnen worden gebouwd door een individu met Basiswinkel vaardigheden en gereedschap toegang.CNC-apparaten worden gebruikt voor het fabriceren
Eventorbot! Open source DIY 3D printer. Gratis plannen

Eventorbot! Open source DIY 3D printer. Gratis plannen

Eventorbot! Opensource 3D-printer. Eenvoudig met minder materiaal. Frame is gemaakt van een enkele 4' lang, 2 1/2" vierkante buis (16 gauge/1.5mm/.0598" dikke, kosten: minder dan $20.00). Met dit ontwerp is er minder plastic delen, sterkere stru
Open Source Solarpad Kit zonne-USB lader

Open Source Solarpad Kit zonne-USB lader

Klik hieronder om naar onze Kickstarter projectpagina voor Solarpad!http://www.Kickstarter.com/projects/249225636/Sola..."Ten slotte, een juiste Solar Charger voor wandelaars en fietsers" - cultus van MacKan een compacte zonne-USB lader laadt ee