<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="da">
	<id>https://www.htxarduino.dk/index.php?action=history&amp;feed=atom&amp;title=Arduino_Lys-avis</id>
	<title>Arduino Lys-avis - Versionshistorie</title>
	<link rel="self" type="application/atom+xml" href="https://www.htxarduino.dk/index.php?action=history&amp;feed=atom&amp;title=Arduino_Lys-avis"/>
	<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Arduino_Lys-avis&amp;action=history"/>
	<updated>2026-06-17T08:56:24Z</updated>
	<subtitle>Versionshistorie for denne side i HTX Arduino</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Arduino_Lys-avis&amp;diff=4089&amp;oldid=prev</id>
		<title>Bar med 26. okt. 2022, 15:53</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Arduino_Lys-avis&amp;diff=4089&amp;oldid=prev"/>
		<updated>2022-10-26T15:53:37Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;da&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Ældre version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Versionen fra 26. okt. 2022, 17:53&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Linje 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Linje 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Fil:Dot-matrix-modul.png|300px|right|thumb|Dot Matrix modul]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Fil:Dot-matrix-modul.png|300px|right|thumb|Dot Matrix modul]]  &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Grundlæggende forudsætninger==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Grundlæggende forudsætninger==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Modulet der anvendes til lysavisen er baseret på en MAX7219 driver, der kan styres af 3 serielle signaler.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Modulet der anvendes til lysavisen er baseret på en MAX7219 driver, der kan styres af 3 serielle signaler.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Arduino_Lys-avis&amp;diff=3939&amp;oldid=prev</id>
		<title>Bar: 1 version importeret</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Arduino_Lys-avis&amp;diff=3939&amp;oldid=prev"/>
		<updated>2022-10-26T12:50:08Z</updated>

		<summary type="html">&lt;p&gt;1 version importeret&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;da&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Ældre version&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Versionen fra 26. okt. 2022, 14:50&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;da&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(Ingen forskel)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Arduino_Lys-avis&amp;diff=3938&amp;oldid=prev</id>
		<title>htx_&gt;Bar: /* Referencer */</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Arduino_Lys-avis&amp;diff=3938&amp;oldid=prev"/>
		<updated>2017-09-29T12:19:13Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Referencer&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ny side&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[Fil:Dot-matrix-modul.png|300px|right|thumb|Dot Matrix modul]]&lt;br /&gt;
==Grundlæggende forudsætninger==&lt;br /&gt;
Modulet der anvendes til lysavisen er baseret på en MAX7219 driver, der kan styres af 3 serielle signaler.&lt;br /&gt;
&lt;br /&gt;
Man kunne vælge at basere det på en færdigskrevet bibliotek&amp;lt;ref name=&amp;quot;github&amp;quot;&amp;gt;[https://github.com/marcmerlin/LED-Matrix/ Henvisning til GitHUB LED-matrix Bibliotek]&amp;lt;/ref&amp;gt;, som ville gøre det enkelt at gå til LED-Matrix-modulet. I stedet er det baseret på software skrevet fra bunden til at styre modulet med. Den grunlæggende software er beskrevet på [[Arduino Dot-Matrix]].&lt;br /&gt;
&lt;br /&gt;
Modulet er købt ved aliexpress.com&amp;lt;ref&amp;gt;[http://www.aliexpress.com/item/MAX7219-Dot-Led-Matrix-Module-MCU-LED-Display-Control-Module-Kit-For-Arduino/1766484563.html Købsside ved aliexpress.com til modulet]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Hardware opkobling==&lt;br /&gt;
For at kunne styre hver enkelt modul, så kan man koble CLK, +5V og GND igennem alle de moduler man ønsker.&lt;br /&gt;
&lt;br /&gt;
Til gengæld skal databenet føres direkte til alle moduler, da det er et andet signal der kommer ud af modulet på D-OUT. Dette gøres ved at fordele signalet via et fumlebræt som vist&lt;br /&gt;
&lt;br /&gt;
For at kunne skille modulerne ad, så får de hver sin CS fra Arduinoen.&lt;br /&gt;
&lt;br /&gt;
Dette kan skitseres som følger:&lt;br /&gt;
&lt;br /&gt;
[[fil:lys-avis-fumle.png|500px|Opstilling med Arduino koblet til en række Dot-matrix-moduler som en lysavis.]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Opstilling med Arduino koblet til en række Dot-matrix-moduler som en lysavis.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
I praksis ser opkoblingen af 6 moduler ud som følger:&lt;br /&gt;
&lt;br /&gt;
[[fil:lys-avis-praktisk.jpg|500px|Opstilling med Arduino koblet til 6 Dot-matrix-moduler som en lysavis.]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Praktisk opstilling med Arduino koblet til 6 Dot-matrix-moduler som en lysavis.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Ideen bag softwaren til lys-avisen==&lt;br /&gt;
For at man kan få lysavisen til at &amp;quot;løbe&amp;quot; hen over alle modulerne, så er man nødt til at genskrive alt indholdet med et fast interval - i dette tilfælde sat til 100 ms.&lt;br /&gt;
&lt;br /&gt;
For kunne gøre lysavisen rimelig universel, så er der lagt et helt karaktersæt ind, så man kan oversætte de givne karakterer til en visning på Dot-matrix displayene.&lt;br /&gt;
&lt;br /&gt;
Starten af lysavisen er at alle moduler er blanke, og når den viste tekst er udskrevet hel, så sættes alle moduler igen blanke inden der sættes den samme tekst op igen.&lt;br /&gt;
&lt;br /&gt;
Som softwaren er konstrueret nu, så starter lysavisen med en konstant tekst efter reset, men man kan via den serielle monitor indlæse en ny tekststreng der vil blive vist. Denne tekststreng må højst være 128 karakterer lang. En ide til en udvidelse kunne være at man gemmer den indlæste tekst i EEPROM, så det er den sidst indskrevne tekst den vågner op med.&lt;br /&gt;
&lt;br /&gt;
==Opbygningen af softwaren==&lt;br /&gt;
Hele softwaren ligger i en [[media:arduino-Dot-Matrix.zip|ZIP-fil]], sammen med de andre eksempler på kode til Dot-Matrix. Lysavisen beskrevet her hedder Lys-Avis.&lt;br /&gt;
&lt;br /&gt;
Som en start defineres alle de hardware-mæssige forudsætninger for Lys-avisen, hvilke ben der anvendes, størrelsen på modulerne størrelsen på de karakterer der defineres, hvor mange karakterer der er defineret, max antal karakterer der kan vises i Lys-avisen og opdaterings-tiden (hvor hurtigt den ruller).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
const byte antalBlok = 6;    // Antallet af blokke der skal vise noget&lt;br /&gt;
const byte charWidth = 6;    // Karakter-bredden i punkter&lt;br /&gt;
const byte blokWidth = 8;    // Blok-bredden i punkter&lt;br /&gt;
const int din = 2;           // Data in ben, fordeles til alle moduler&lt;br /&gt;
const int cs [antalBlok] {3, 5, 6, 7, 8, 9}; // CS-ben, et til hvert modul&lt;br /&gt;
const int clk = 4;           // Clock-ben - til første modul, linkes videre&lt;br /&gt;
const byte antalCh = 102;    // Antallet i charSet&lt;br /&gt;
const byte maxStr = 128;     // Max antal viste karakterer, må ikke være over 255&lt;br /&gt;
const int updateTime = 100;  // Antal ms mellen hver opdatering&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Karakter-tabellen===&lt;br /&gt;
Karaktererne opbygges i en matrix der er 5 dots bred og 8 dots høj, hvor de to nederste dots reserveres til de karakterer der går &amp;quot;under linjen&amp;quot;, så for at repræsentere en dot skal der angives en bit høj, og en bit lav, hvis der ikke er en dot, og da karakteren netop er 8 bit høj, så passer det fint med en byte, så definitionen af en karakter kan gemmes i 5 bytes (bredden af en karakter). Dette passer også så fornemt med at man tænder 8 dots af gangen ved at kommunikere en byte over, så for at vise en karakter skal der blot overføres 5 byte plus en byte der er 0 til afstanden mellem karaktererne.&lt;br /&gt;
&lt;br /&gt;
For at illustrere hvordan karaterene defineres vises her eksemplet for 3 karakterer A, B og C. I karaktertabellen er det valgt at bunden af karakteren er de mest betyden bits i byten.&lt;br /&gt;
&lt;br /&gt;
Karaktererne startes med at blive tegnet op på et kvadreret papir, og ser ud som følger:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  *    ***     *** &lt;br /&gt;
 * *   *  *   *   *&lt;br /&gt;
 * *   ****   *&lt;br /&gt;
*****  *   *  *&lt;br /&gt;
*   *  *   *  *   *&lt;br /&gt;
*   *  ****    ***&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ved at omdanne dette til 0&amp;#039;er og 1&amp;#039;er, så får man følgende mønster:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00100 11100 01110&lt;br /&gt;
01010 10010 10001&lt;br /&gt;
01010 11110 10000&lt;br /&gt;
11111 10001 10000&lt;br /&gt;
10001 10001 10001&lt;br /&gt;
10001 11110 01110&lt;br /&gt;
00000 00000 00000&lt;br /&gt;
00000 00000 00000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis man for A&amp;#039;s vedkommende tolker dette som binære tal læst lodret med mindst betydende bit øverst, så får man følgende 5 binære tal, der kan oversættes til Hexadicimale tal som vist her:&amp;lt;br /&amp;gt;&lt;br /&gt;
00111000 - 0x38&amp;lt;br /&amp;gt;&lt;br /&gt;
00001110 - 0x0E&amp;lt;br /&amp;gt;&lt;br /&gt;
00001001 - 0x09&amp;lt;br /&amp;gt;&lt;br /&gt;
00001110 - 0x0E&amp;lt;br /&amp;gt;&lt;br /&gt;
00111000 - 0x38&lt;br /&gt;
&lt;br /&gt;
For at kunne kunne identificere den enkelte karakter i karaktertabellen, så anvendes [[ASCII]]-tabellen, der knytter et bestemt tal (0-255) til en bestemt karakter, hvor A, B og C har ASCII-numrene 65, 66 og 67. Ud fra dette kan man definere A, B og C som følger: &lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  {  65, 0x38, 0x0E, 0x09, 0x0E, 0x38 }, // A&lt;br /&gt;
  {  66, 0x3F, 0x25, 0x25, 0x26, 0x18 }, // B&lt;br /&gt;
  {  67, 0x1E, 0x21, 0x21, 0x21, 0x12 }, // C&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Med lidt tålmodighed kan alle de 102 karakterer der er defineret opstilles i tabellen charSet:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
// Hele karaktertabellen, der definerer visningen af karakter-numrene&lt;br /&gt;
// Første ciffer et karakteren ASCII nummer&lt;br /&gt;
// De 5 følgende er de enkelte punkter defineret som HEX-tal&lt;br /&gt;
// Alle karakterer er 5x8 punkter, efterfulgt af et punkts mellemrum&lt;br /&gt;
const byte charSet [antalCh][6] {&lt;br /&gt;
  {   0, 0x55, 0xAA, 0x55, 0xAA, 0x55 }, // Ikke eksisterende&lt;br /&gt;
  {  32, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Space&lt;br /&gt;
  {  33, 0x00, 0x00, 0x2F, 0x00, 0x00 }, // !&lt;br /&gt;
  {  34, 0x00, 0x06, 0x00, 0x06, 0x00 }, // &amp;quot;&lt;br /&gt;
  {  35, 0x14, 0x3E, 0x14, 0x3E, 0x14 }, // #&lt;br /&gt;
  {  36, 0x24, 0x2A, 0x7F, 0x2A, 0x12 }, // $&lt;br /&gt;
  {  37, 0x22, 0x10, 0x08, 0x04, 0x22 }, // %&lt;br /&gt;
  {  38, 0x14, 0x2A, 0x2C, 0x10, 0x28 }, // &amp;amp;&lt;br /&gt;
  {  39, 0x00, 0x00, 0x06, 0x00, 0x00 }, // &amp;#039;&lt;br /&gt;
  {  40, 0x00, 0x00, 0x3E, 0x41, 0x00 }, // (&lt;br /&gt;
  {  41, 0x00, 0x41, 0x3E, 0x00, 0x00 }, // )&lt;br /&gt;
  {  42, 0x24, 0x18, 0x0E, 0x18, 0x24 }, // *&lt;br /&gt;
  {  43, 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +&lt;br /&gt;
  {  44, 0x00, 0x60, 0x20, 0x00, 0x00 }, // ,&lt;br /&gt;
  {  45, 0x00, 0x08, 0x08, 0x08, 0x00 }, // -&lt;br /&gt;
  {  46, 0x00, 0x30, 0x30, 0x00, 0x00 }, // .&lt;br /&gt;
  {  47, 0x20, 0x10, 0x08, 0x04, 0x02 }, // /&lt;br /&gt;
  {  48, 0x1E, 0x21, 0x21, 0x1E, 0x00 }, // 0&lt;br /&gt;
  {  49, 0x00, 0x22, 0x3F, 0x20, 0x00 }, // 1&lt;br /&gt;
  {  50, 0x22, 0x31, 0x29, 0x26, 0x00 }, // 2&lt;br /&gt;
  {  51, 0x12, 0x21, 0x2D, 0x12, 0x00 }, // 3&lt;br /&gt;
  {  52, 0x0F, 0x08, 0x08, 0x3F, 0x00 }, // 4&lt;br /&gt;
  {  53, 0x17, 0x25, 0x25, 0x19, 0x00 }, // 5&lt;br /&gt;
  {  54, 0x1E, 0x25, 0x25, 0x18, 0x00 }, // 6&lt;br /&gt;
  {  55, 0x21, 0x11, 0x09, 0x07, 0x00 }, // 7&lt;br /&gt;
  {  56, 0x1A, 0x25, 0x25, 0x1A, 0x00 }, // 8&lt;br /&gt;
  {  57, 0x06, 0x29, 0x29, 0x1E, 0x00 }, // 9&lt;br /&gt;
  {  58, 0x00, 0x00, 0x24, 0x00, 0x00 }, // :&lt;br /&gt;
  {  59, 0x00, 0x40, 0x24, 0x00, 0x00 }, // ;&lt;br /&gt;
  {  60, 0x08, 0x14, 0x22, 0x41, 0x00 }, // &amp;lt;&lt;br /&gt;
  {  61, 0x00, 0x14, 0x14, 0x14, 0x00 }, // =&lt;br /&gt;
  {  62, 0x41, 0x22, 0x14, 0x08, 0x00 }, // &amp;gt;&lt;br /&gt;
  {  63, 0x02, 0x01, 0xB1, 0x09, 0x06 }, // ?&lt;br /&gt;
  {  64, 0x3E, 0x49, 0x55, 0x5D, 0x4E }, // @&lt;br /&gt;
  {  65, 0x38, 0x0E, 0x09, 0x0E, 0x38 }, // A&lt;br /&gt;
  {  66, 0x3F, 0x25, 0x25, 0x26, 0x18 }, // B&lt;br /&gt;
  {  67, 0x1E, 0x21, 0x21, 0x21, 0x12 }, // C&lt;br /&gt;
  {  68, 0x3F, 0x21, 0x21, 0x21, 0x1E }, // D&lt;br /&gt;
  {  69, 0x3F, 0x25, 0x25, 0x25, 0x21 }, // E&lt;br /&gt;
  {  70, 0x3F, 0x05, 0x05, 0x05, 0x01 }, // F&lt;br /&gt;
  {  71, 0x1E, 0x21, 0x21, 0x29, 0x1A }, // G&lt;br /&gt;
  {  72, 0x3F, 0x04, 0x04, 0x04, 0x3F }, // H&lt;br /&gt;
  {  73, 0x00, 0x21, 0x3F, 0x21, 0x00 }, // I&lt;br /&gt;
  {  74, 0x11, 0x21, 0x21, 0x21, 0x1F }, // J&lt;br /&gt;
  {  75, 0x3F, 0x08, 0x0C, 0x12, 0x21 }, // K&lt;br /&gt;
  {  76, 0x3F, 0x20, 0x20, 0x20, 0x20 }, // L&lt;br /&gt;
  {  77, 0x3F, 0x02, 0x0C, 0x02, 0x3F }, // M&lt;br /&gt;
  {  78, 0x3F, 0x06, 0x08, 0x10, 0x3F }, // N&lt;br /&gt;
  {  79, 0x1E, 0x21, 0x21, 0x21, 0x1E }, // O&lt;br /&gt;
  {  80, 0x3F, 0x09, 0x09, 0x09, 0x06 }, // P&lt;br /&gt;
  {  81, 0x1E, 0x21, 0x21, 0x11, 0x2E }, // Q&lt;br /&gt;
  {  82, 0x3F, 0x05, 0x0D, 0x15, 0x22 }, // R&lt;br /&gt;
  {  83, 0x12, 0x25, 0x29, 0x29, 0x12 }, // S&lt;br /&gt;
  {  84, 0x01, 0x01, 0x3F, 0x01, 0x01 }, // T&lt;br /&gt;
  {  85, 0x1F, 0x20, 0x20, 0x20, 0x1F }, // U&lt;br /&gt;
  {  86, 0x07, 0x18, 0x20, 0x18, 0x07 }, // V&lt;br /&gt;
  {  87, 0x07, 0x38, 0x06, 0x38, 0x07 }, // W&lt;br /&gt;
  {  88, 0x23, 0x14, 0x08, 0x14, 0x23 }, // X&lt;br /&gt;
  {  89, 0x03, 0x04, 0x38, 0x04, 0x03 }, // Y&lt;br /&gt;
  {  90, 0x31, 0x29, 0x2D, 0x25, 0x23 }, // Z&lt;br /&gt;
  {  91, 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [&lt;br /&gt;
  {  92, 0x02, 0x04, 0x08, 0x10, 0x20 }, // \&lt;br /&gt;
  {  93, 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ]&lt;br /&gt;
  {  94, 0x00, 0x02, 0x01, 0x02, 0x00 }, // ^&lt;br /&gt;
  {  95, 0x40, 0x40, 0x40, 0x40, 0x40 }, // _&lt;br /&gt;
  {  96, 0x00, 0x01, 0x02, 0x00, 0x00 }, // `&lt;br /&gt;
  { 198, 0x38, 0x06, 0x1D, 0x25, 0x21 }, // Æ&lt;br /&gt;
  { 216, 0x2E, 0x11, 0x2D, 0x22, 0x1D }, // Ø&lt;br /&gt;
  { 197, 0x30, 0x1C, 0x15, 0x1C, 0x30 }, // Å&lt;br /&gt;
  {  97, 0x18, 0x24, 0x24, 0x1C, 0x20 }, // a&lt;br /&gt;
  {  98, 0x20, 0x1F, 0x24, 0x24, 0x18 }, // b&lt;br /&gt;
  {  99, 0x18, 0x24, 0x24, 0x24, 0x00 }, // c&lt;br /&gt;
  { 100, 0x18, 0x24, 0x24, 0x1F, 0x20 }, // d&lt;br /&gt;
  { 101, 0x1C, 0x2A, 0x2A, 0x2C, 0x00 }, // e&lt;br /&gt;
  { 102, 0x00, 0x04, 0x3F, 0x05, 0x00 }, // f&lt;br /&gt;
  { 103, 0x18, 0xA4, 0xA4, 0xA4, 0x78 }, // g&lt;br /&gt;
  { 104, 0x3F, 0x04, 0x04, 0x38, 0x00 }, // h&lt;br /&gt;
  { 105, 0x00, 0x00, 0x3A, 0x00, 0x00 }, // i&lt;br /&gt;
  { 106, 0x00, 0x80, 0x80, 0x7A, 0x00 }, // j&lt;br /&gt;
  { 107, 0x3F, 0x10, 0x18, 0x24, 0x00 }, // k&lt;br /&gt;
  { 108, 0x00, 0x1F, 0x20, 0x00, 0x00 }, // l&lt;br /&gt;
  { 109, 0x38, 0x04, 0x18, 0x04, 0x38 }, // m&lt;br /&gt;
  { 110, 0x3C, 0x08, 0x04, 0x38, 0x00 }, // n&lt;br /&gt;
  { 111, 0x18, 0x24, 0x24, 0x18, 0x00 }, // o&lt;br /&gt;
  { 112, 0xF8, 0x24, 0x24, 0x18, 0x00 }, // p&lt;br /&gt;
  { 113, 0x18, 0x24, 0x24, 0xF8, 0x00 }, // q&lt;br /&gt;
  { 114, 0x04, 0x38, 0x04, 0x08, 0x00 }, // r&lt;br /&gt;
  { 115, 0x24, 0x2A, 0x2A, 0x12, 0x00 }, // s&lt;br /&gt;
  { 116, 0x00, 0x02, 0x1F, 0x22, 0x00 }, // t&lt;br /&gt;
  { 117, 0x1C, 0x20, 0x20, 0x1C, 0x20 }, // u&lt;br /&gt;
  { 118, 0x04, 0x18, 0x20, 0x18, 0x04 }, // v&lt;br /&gt;
  { 119, 0x0C, 0x30, 0x18, 0x30, 0x0C }, // w&lt;br /&gt;
  { 120, 0x22, 0x14, 0x08, 0x14, 0x22 }, // x&lt;br /&gt;
  { 121, 0x1C, 0xA0, 0xA0, 0x7C, 0x00 }, // y&lt;br /&gt;
  { 122, 0x24, 0x34, 0x2C, 0x24, 0x00 }, // z&lt;br /&gt;
  { 123, 0x00, 0x08, 0x36, 0x41, 0x00 }, // {&lt;br /&gt;
  { 124, 0x00, 0x00, 0x7F, 0x00, 0x00 }, // |&lt;br /&gt;
  { 125, 0x00, 0x41, 0x36, 0x08, 0x00 }, // }&lt;br /&gt;
  { 126, 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~&lt;br /&gt;
  { 230, 0x1C, 0x22, 0x1C, 0x2A, 0x2C }, // æ&lt;br /&gt;
  { 248, 0x2C, 0x12, 0x2A, 0x24, 0x1A }, // ø&lt;br /&gt;
  { 229, 0x18, 0x24, 0x25, 0x1C, 0x20 } // å&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Initialisering af programmet===&lt;br /&gt;
Initialiseringen af programmet sker som det er standard i [[setup()]].&lt;br /&gt;
&lt;br /&gt;
Den serielle port sættes op, så man kan kommunikere via den serielle port og lægge nye tekster ind.&lt;br /&gt;
&lt;br /&gt;
De ben der skal anvendes til at kommunikere med modulerne skal sættes op til output og sættes til det rigtige niveau. Da der er flere moduler skal alle CS-benene sættes op, og i samme loop initialiseres registrene i blokkene når benene er sat op og visningen i displayet slettes, så der er klart til at lys-avisen kan vise tekst.&lt;br /&gt;
&lt;br /&gt;
Til slut skrives en velkomst-besked på den serielle port, der indikerer at man kan skrive en ny tekst ind i den serielle monitor.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  // Sæt de serielle udgange:&lt;br /&gt;
  pinMode (din, OUTPUT);&lt;br /&gt;
  pinMode (clk, OUTPUT);&lt;br /&gt;
  // Sæt start-niveauerne:&lt;br /&gt;
  digitalWrite(clk, LOW);&lt;br /&gt;
  for (int n = 0; n &amp;lt; antalBlok; n++) {&lt;br /&gt;
    pinMode (cs[n], OUTPUT);&lt;br /&gt;
    digitalWrite(cs[n], HIGH);&lt;br /&gt;
    // Initialiser alle blokke&lt;br /&gt;
    disp(n, 0x0B, 0x07);  // Scan Limit - Display alle bit&lt;br /&gt;
    disp(n, 0x09, 0x00);  // Decode Mode - Ingen dekodning&lt;br /&gt;
    disp(n, 0x0C, 0x01);  // Shutdown - Normal operation&lt;br /&gt;
    disp(n, 0x0F, 0x00);  // Display Test - Slået fra&lt;br /&gt;
    disp(n, 0x0A, 0x01);  // Intensity - low level&lt;br /&gt;
    // slet visning i alle blokke&lt;br /&gt;
    for (int i = 1; i &amp;lt; 9; i++) {&lt;br /&gt;
      disp(n, i, 0);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  Serial.print(&amp;quot;Skriv tekst ind her - husk at sl&amp;quot;);&lt;br /&gt;
  Serial.write(229);  // å&lt;br /&gt;
  Serial.println(&amp;quot; CR LF til&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;-------------------------------------------&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Kommunikation med modulerne===&lt;br /&gt;
Rutinerne til at clocke data ind i modulerne med stammer fra [[Arduino Dot-Matrix|Dot-matrix testen]], hvor den første rutine til at sende en byte med er præcist den samme, mens rutinen disp er modificeret lidt, så den også angiver hvilket modul der skal kommunikeres med, det er parameteren blok der angiver det. De to andre parametre adr og data er den adresse der skal skrives til (hvilken kolonne af dots det er) og data er det indhold der skal skrives i den kolonne.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
// Funktion der clocker en byte ud til displayet&lt;br /&gt;
void sendByte(byte data) {&lt;br /&gt;
  for (int n = 0; n &amp;lt; 8; n++) {&lt;br /&gt;
    digitalWrite(din, data &amp;amp; 0x80);&lt;br /&gt;
    data &amp;lt;&amp;lt;= 1;&lt;br /&gt;
    digitalWrite(clk, HIGH);&lt;br /&gt;
    digitalWrite(clk, LOW);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion der vælger blokken og clocker adresse og data til blokken&lt;br /&gt;
void disp(byte blok, byte adr, byte data) {&lt;br /&gt;
  digitalWrite(cs[blok], LOW);&lt;br /&gt;
  sendByte(adr);&lt;br /&gt;
  sendByte(data);&lt;br /&gt;
  digitalWrite(cs[blok], HIGH);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variabler i programmet===&lt;br /&gt;
Fordi en del af variablerne skal gemmes fra gang til gang at [[loop()]] kaldes, så er de erklæret globalt, og for at holde variablerne samlet er de alle erklæret her.&lt;br /&gt;
&lt;br /&gt;
De 4 første variabler har med modtagelsen af en streng fra den serielle port at gøre.&lt;br /&gt;
&lt;br /&gt;
De resterende variabler har med styringen af udskriften af den gemte streng at gøre, hvor strengen som standard sættes til &amp;quot;Lysavis lavet ved Holstebro HTX - 2015&amp;quot;, så der kommer en fornuftig visning når programmet vågner. Til slut er der en test-variabel.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
byte ch;             // Karakter modtaget serielt&lt;br /&gt;
boolean OK;          // Er katakteren fundet&lt;br /&gt;
char modtStreng [maxStr];  // Streng til modtagelse&lt;br /&gt;
byte modtPtr = 0;    // Pointer til næste karakter der skal modtages&lt;br /&gt;
&lt;br /&gt;
int ptr = 0;         // Pointer der angiver hvor visningen er kommet til&lt;br /&gt;
char streng [maxStr] = &amp;quot;Lysavis lavet ved Holstebro HTX - 2015&amp;quot;;&lt;br /&gt;
byte strAntal = 38;  // Visnings-streng og antallet i den&lt;br /&gt;
int strPtr;          // Punkt-pointer ind i den viste streng&lt;br /&gt;
long time = 0;       // Sidste visnings-tidspunkt&lt;br /&gt;
byte data;           // Byte der skal clockes ud til displayet&lt;br /&gt;
byte blok;           // Angivelsen af blokken der skal skrives til&lt;br /&gt;
byte row;            // Angivelsen af hvilken række i karakteren&lt;br /&gt;
byte strNr;          // Angivelsen af hvilken karater i strengen der vises&lt;br /&gt;
&lt;br /&gt;
byte timeCnt = 0;    // Testvariabel til visning af udlæsningstid&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Modtagelse af karakterer til en streng===&lt;br /&gt;
Hovedsoftwaren bliver afviklet i [[loop()]], hvor den kaldes med forskelligt interval, alt efter hvor lang tid koden tager i loopet. Dette er koden forsøgt skrevet til, så man kommer igennem hurtigst muligt, hvis der ikke skal udføres noget.&lt;br /&gt;
&lt;br /&gt;
Den første del af koden i loop() som er vist herunder sørger for at modtage fra den serielle port, hvis der kommer noget. Denne kode tager højde for at der kan være længere interval mellem den bliver kaldt (op til 17 ms viser det sig i en teste foretager længere nede med 6 moduler tilkoblet).&lt;br /&gt;
&lt;br /&gt;
Der kigges først på om der er karakterer tilgængelige, og hvis der ikke er det, så vil der ikke ske mere i koden. Er der karakterer tilgængelige, så loopes der indtil man har tømt bufferen (max 64 karakterer i Serial-modulet). Hver enkelt karakter der modtages echoes tilbage for brugervenlighedens skyld.&lt;br /&gt;
&lt;br /&gt;
Hvis det er en almindelig karakter, så lagres den i en buffer (et array) og pointeren sættes klar til næste karakter, hvis man ikke kommer ud over bufferens grænse (128 karakterer), ellers tabes karakteren, da den alligevel ikke kan håndteres.&lt;br /&gt;
&lt;br /&gt;
For at afslutte sendingen skal Serial Monitor sættes op til at sende CR som linje afslutning. Dette detekteres der på her (en LF ignoreres for en sikkerheds skyld) og når der modtages en CR, så overføres hele den modtagne streng til visnings-strengen, antallet registreres og der gøres klar til en ny modtagelse (pointeren nulstilles).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void loop() {&lt;br /&gt;
  while (Serial.available() &amp;gt; 0) {  // Modtages der nye karkterer&lt;br /&gt;
    // Læs en karakter&lt;br /&gt;
    ch = Serial.read();&lt;br /&gt;
    Serial.write(ch);&lt;br /&gt;
    /* Til visning af karakter nummer - udkommenteret&lt;br /&gt;
    Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
    Serial.println(ch);&lt;br /&gt;
    */&lt;br /&gt;
    if (ch == 13) {   // Ved linje slut - CR - gemmes den&lt;br /&gt;
      for (int n = 0; n &amp;lt; modtPtr; n++) {&lt;br /&gt;
        streng[n] = modtStreng[n];&lt;br /&gt;
      }&lt;br /&gt;
      // Antallet i linjen registreres og der gøres klar til modtagelse af ny linje&lt;br /&gt;
      strAntal = modtPtr;&lt;br /&gt;
      modtPtr = 0;&lt;br /&gt;
    } else if (ch == 10) { // Ignorer LF&lt;br /&gt;
    } else {  // Gem den modtagne karakter&lt;br /&gt;
      modtStreng[modtPtr] = ch;&lt;br /&gt;
      if (modtPtr &amp;lt; maxStr) {&lt;br /&gt;
        modtPtr++;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visning af tekststengen i Dot-Matrix modulerne===&lt;br /&gt;
Denne del af koden aktiveres hver gang funktionen millis() er blevet updateTime større end sidste opdatering. Dette gør at koden her bliver afviklet 10 gange i sekundet (med updateTime på 100, hvarende til 100ms).&lt;br /&gt;
&lt;br /&gt;
Koden baserer sig på 2 pointere der begge bevæger sig i kolonner, og altså har 6 trin for hver karakter. Den første pointer &amp;#039;&amp;#039;&amp;#039;ptr&amp;#039;&amp;#039;&amp;#039; løber hen gennem 6 gange hele strengens længde plus det antal dots der er i alle blokke (det giver et tomt ophold fra slut tekst til ny start af samme tekst på netop alle blokke). Den næste poniter &amp;#039;&amp;#039;&amp;#039;strPtr&amp;#039;&amp;#039;&amp;#039; løber for hver visning et antal igennem svarende til det antal dots der er i alle blokke. Tricket er at den starter på den anden pointer minus antal dots i blokkene, hvilket gør at den kan starte med en negativ værdi.&lt;br /&gt;
&lt;br /&gt;
I gennemløbet af alle dots tjekkes om strPtr er negativ, hvor der så vises blank (det etablerer mellemrummet mellem start og slut). Er strPtr positiv beregnes hvilken række i karakteren der skal vises. Hvis det er den 6. så er det mellemrummet mellem karaktererne, så vises der 0 så der bliver et mellemrum. Er det inde i karakteren, så tjekkes der om den aktuelle karakter ligger inden for strengen, og hvis den gør det, så ledes karatertabellen igennem for at finde oversættelsen af den ønskede karakter. Findes den ikke sættes visningen til en dummy-karakter for at indikere at karakteren ikke kan vises.&lt;br /&gt;
&lt;br /&gt;
Når opslaget til karakteren er fundet, så hentes den ønskede række frem fra karaktertabellen og rækken clockes ud med de beskrevne rutiner, og der sættes frem til næste række i modulerne.&lt;br /&gt;
&lt;br /&gt;
Når alle rækker i modulerne er vist, så sættes pointeren ptr en frem, så visningen rykker sig en frem ved hver visning.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  if (time + updateTime &amp;lt; millis()) { // Opdater 10 gange i sekundet  &lt;br /&gt;
    time = millis();&lt;br /&gt;
    // Begræns visningen til strenges antal punkter + bredden af blokkene&lt;br /&gt;
    if (ptr &amp;gt; antalBlok * blokWidth + strAntal * charWidth) {&lt;br /&gt;
      ptr = 0;&lt;br /&gt;
    }&lt;br /&gt;
    // Find hvor strengens start er&lt;br /&gt;
    strPtr = ptr - antalBlok * blokWidth;&lt;br /&gt;
    // Løb hen gennem alle punkter i blokkene&lt;br /&gt;
    for (int n = 0; n &amp;lt; antalBlok * blokWidth; n++) {&lt;br /&gt;
      if (strPtr &amp;lt; 0) {  // Vis tomt mellem start og slut af streng&lt;br /&gt;
        data = 0;&lt;br /&gt;
      } else {   // Find den række der skal clockes ud&lt;br /&gt;
        row = strPtr % charWidth;&lt;br /&gt;
        if (row == (charWidth - 1)) {  // Tomt mellemrum mellem karaktererne&lt;br /&gt;
          data = 0;&lt;br /&gt;
        } else {  // Find den aktuelle række&lt;br /&gt;
          row++;&lt;br /&gt;
          strNr = strPtr / charWidth;&lt;br /&gt;
          if (strNr &amp;gt;= strAntal) {&lt;br /&gt;
            data = 0;&lt;br /&gt;
          } else {&lt;br /&gt;
            OK = false;&lt;br /&gt;
            for (int i = 0; i &amp;lt; antalCh; i++) { // Led efter den aktuelle karakter i karaktersættet&lt;br /&gt;
              if (byte(streng[strNr]) == charSet[i][0]) {&lt;br /&gt;
                data = i;&lt;br /&gt;
                OK = true;&lt;br /&gt;
                break;&lt;br /&gt;
              }&lt;br /&gt;
            }&lt;br /&gt;
            if (! OK) {&lt;br /&gt;
              data = 0;  // Sæt fejlvisning hvis den ikke er fundet&lt;br /&gt;
            }&lt;br /&gt;
            data = charSet[data][row];  // Hent det der skal clockes ud&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      // Clock den aktuelle byte ud (8 punkter lodret)&lt;br /&gt;
      blok = antalBlok - n / blokWidth - 1;&lt;br /&gt;
      disp(blok, n % blokWidth + 1, data);&lt;br /&gt;
      strPtr++;&lt;br /&gt;
    }&lt;br /&gt;
    // ch = streng[strNr];&lt;br /&gt;
    ptr++;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test af afviklingstiden===&lt;br /&gt;
Den sidste del af koden der her er kommenteret ud er taget med for at kunne få en ide om hvor lang tid koden tager om at gennemløbe en hel udscanning af alle moduler.&lt;br /&gt;
&lt;br /&gt;
Ved en test med 6 moduler viste tiderne skift fra 12 ms hvor der ikke var tekst der skulle vises op til 17 ms hvor det var udelukkende karakterer sidst i karaktertabellen (kræver søgning i tabellen hver gang). Dette betyder at softwaren kan håndtere op til omkring 36 moduler før den får tidsproblemer ved en opdatering på 100 ms, mens man max kan håndtere ca. 18 moduler med en opdatering på 50 ms.&lt;br /&gt;
&lt;br /&gt;
Det er ikke afprøvet hvad der sker hvis man bryder grænserne for opdatering, men det ville sikkert kunne give problemer med den serielle kommunikation, fx at man ville kunne miste karakterer i det modtagne.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    // Analyse af hvor lang tid optegningen tage - resultat 12 - 17 ms&lt;br /&gt;
    // afhængigt af hvor i karaktertabellen det hentes&lt;br /&gt;
    /* udkommenteret&lt;br /&gt;
    timeCnt++;&lt;br /&gt;
    if (timeCnt == 10) {&lt;br /&gt;
      timeCnt = 0;&lt;br /&gt;
      Serial.println(millis() - time);&lt;br /&gt;
    } */&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Demonstration af funktionen==&lt;br /&gt;
Herunder demonstreres hvordan lys-avisen fungerer i en lille video.&amp;lt;br /&amp;gt;&lt;br /&gt;
{{#ev:youtube|8OBkaUvqumo}} &amp;lt;br /&amp;gt;&lt;br /&gt;
[https://youtu.be/8OBkaUvqumo Direkte link]&lt;br /&gt;
&lt;br /&gt;
==Alternativ kodning med et bibliotek==&lt;br /&gt;
Når man nu har et bibliotek til modulet, så kan det være en god ide at finde ud af hvilke fordele og ulemper der er ved at anvende biblioteket, når vi nu har fundet ud af hvordan modulet grundlæggende virker.&lt;br /&gt;
&lt;br /&gt;
Hele softwaren ligger i en [[media:arduino-Dot-Matrix.zip|ZIP-fil]], sammen med de andre eksempler på kode til Dot-Matrix. Lysavisen med den nye biblioteks-kode som er beskrevet her hedder Lys-Avis2.&lt;br /&gt;
&lt;br /&gt;
===Hardware med biblioteket===&lt;br /&gt;
Ved lidt søgning på nettet (specielt Youtube) kan man finde ud af at modulet lægger op til at man kan daisy-chaine alle signalerne i modulerne (det er også det der virker mest logisk), således at det kun er det første modul der forbindes til arduinoen (3 udgange, GND og +5V). Næste modul forbindes så med alle 5 signaler til de 5 udgange, osv.&lt;br /&gt;
&lt;br /&gt;
Dette giver en opstilling som vist her:&lt;br /&gt;
&lt;br /&gt;
[[fil:lys-avis-bibliotek.jpg|Lys-avis Hardware lavet med biblioteksmodulet|600px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Lys-avis Hardware lavet med biblioteksmodulet&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Biblioteks-software===&lt;br /&gt;
Selve biblioteket&amp;lt;ref name=&amp;quot;github&amp;quot;&amp;gt;&amp;lt;/ref&amp;gt; skal selvfølgelig installeres i Arduinos IDE som et af [[Arduinos Biblioteker]]. Biblioteket hedder LedControl, men kan også søges frem ved at søge i bibliotekerne på MAX7219.&lt;br /&gt;
&lt;br /&gt;
For at få kontakt til biblioteket skal det includes og biblioteket skal initialiseres med de 3 pins det er forbundet til, som vist i koden herunder:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;LedControl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const byte antalBlok = 6;    // Antallet af blokke der skal vise noget&lt;br /&gt;
/*&lt;br /&gt;
 første pin (2) er forbundet til DataIn (DIN)&lt;br /&gt;
 anden pin (4) er forbundet til CLK &lt;br /&gt;
 tredje pin (3) er forbundet til LOAD (CS) &lt;br /&gt;
*/&lt;br /&gt;
LedControl lc=LedControl(2, 4, 3, antalBlok);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Herefter kan vi henvende os til objektet &amp;#039;&amp;#039;&amp;#039;lc&amp;#039;&amp;#039;&amp;#039; med de metoder der ligger i biblioteks-softwaren.&lt;br /&gt;
&lt;br /&gt;
Man kan finde en nærmere omtale af biblioteket&amp;lt;ref&amp;gt;[http://playground.arduino.cc/Main/LedControl Arduino Playgraound omtale an ledControl]&amp;lt;/ref&amp;gt; på Arduinos playground.&lt;br /&gt;
&lt;br /&gt;
===Initialisering af modulerne===&lt;br /&gt;
Initialiseringen kommer til at se noget anderledes ud, da modulerne kontaktes med nogle lidt anderledes metoder, specielt når man skal have fat i special-registrene, så der har de eksempler der ligger i LedControl biblioteket være gode at &amp;quot;låne&amp;quot; fra.&lt;br /&gt;
&lt;br /&gt;
[[setup()]] kommer til at se ud som følger:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  for (int n = 0; n &amp;lt; antalBlok; n++) {&lt;br /&gt;
    // Initialiser alle blokke&lt;br /&gt;
    /* MAX72XX er i power-saving mode ved start, derfor skal den ud af shutdown */&lt;br /&gt;
    lc.shutdown(n,false);&lt;br /&gt;
    /* Set brightness til et lavt niveau, så Arduinoen kan forsyne */&lt;br /&gt;
    lc.setIntensity(n,1);&lt;br /&gt;
    /* Slet indholdet i displayet */&lt;br /&gt;
    lc.clearDisplay(n);&lt;br /&gt;
  } &lt;br /&gt;
  Serial.print(&amp;quot;Skriv tekst ind her - husk at sl&amp;quot;);&lt;br /&gt;
  Serial.write(229);  // å&lt;br /&gt;
  Serial.println(&amp;quot; CR LF til&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;-------------------------------------------&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Initialiseringen af den serielle kommunikation er ikke anderledes.&lt;br /&gt;
&lt;br /&gt;
===Kommunikation med seriel og moduler===&lt;br /&gt;
Der er ikke ændret på kommunikationen med den serielle monitor, så det er fuldstændigt den samme kode.&lt;br /&gt;
&lt;br /&gt;
Kommunikationen med modulerne ligger nu i bibliotekerne, så de to rutiner der var før kan nu slettes.&lt;br /&gt;
&lt;br /&gt;
Alle variabler til at kommunikere serielt med og til udlæsningen af karakterer er stort set de samme, så der er ikke rettet noget i dem.&lt;br /&gt;
&lt;br /&gt;
===Udlæsning til modulerne===&lt;br /&gt;
For at udlæse til modulerne er det stort set den samme kode der anvendes, da der hver gang lysavisen skal rykkes skal analyseres hvilke karakterer der skal sendes, hvor de er i karaktertabellen og hvilke data der skal kommunikeres til modulerne.&lt;br /&gt;
&lt;br /&gt;
Den eneste ændring der er foretaget i den gamle kode er der hvor den byte der skal clockes ud til modulerne sendes. Dette bliver nu gjort med metoden &amp;#039;&amp;#039;&amp;#039;setRow&amp;#039;&amp;#039;&amp;#039; som vist i følgende kode:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
      // Clock den aktuelle byte ud (8 punkter lodret)&lt;br /&gt;
      blok = antalBlok - n / blokWidth - 1;&lt;br /&gt;
      lc.setRow(blok, n % blokWidth, data);&lt;br /&gt;
      strPtr++;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test af udlæsningstiden===&lt;br /&gt;
Som det til dels var forventet, så er det langsommere at læse data ud gennem alle moduler.&lt;br /&gt;
&lt;br /&gt;
Ved en test med 6 moduler blev der målt en udlæsningstid på 83 til 87 ms, hvilket gør at med 100 ms opdateringstid, der kan der ikke føjes flere moduler på, hvis det eller skal kunne lade sig gøre at modtage noget fra den serielle port, så denne udlæsningsform begrænser altså tiden en hel del.&lt;br /&gt;
&lt;br /&gt;
==Software med EEPROM funktion==&lt;br /&gt;
Som beskrevet i starten kan det være smart at man gemmer teksten i en EEPROM, så man kan få Arduinoen til at huske den sidst indtastede tekst, selvom strømmen forsvinder.&lt;br /&gt;
&lt;br /&gt;
Hele softwaren ligger i en [[media:arduino-Dot-Matrix.zip|ZIP-fil]], sammen med de andre eksempler på kode til Dot-Matrix. Lysavisen med EEPROM-kode som er beskrevet her hedder Lys-Avis3.&lt;br /&gt;
&lt;br /&gt;
===Rettelser i Setup()===&lt;br /&gt;
For at man kan se om der ligger en tekst i EEPROM, så læses antallet af karakterer i den første adresse i EEPROM. Hvis dette tal ligger over 0 og under længden af den maksimale streng, så læses alle de angivne karakterer fra EEPROM.&lt;br /&gt;
&lt;br /&gt;
Dette gøres i koden her, som et placeret i setup():&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  strAntal = EEPROM.read(0);  // Læs antallet af gemte karakterer&lt;br /&gt;
  if (strAntal &amp;gt; 0 &amp;amp;&amp;amp; strAntal &amp;lt; maxStr) {  // Hvis der ligger en standard streng i EEPROM  &lt;br /&gt;
    for (int n = 0; n &amp;lt; strAntal; n++) {&lt;br /&gt;
      ch = EEPROM.read(n+1);&lt;br /&gt;
      streng[n] = char(ch);&lt;br /&gt;
    }&lt;br /&gt;
  } else {&lt;br /&gt;
    strAntal = 38;  // Ellers brug default&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis ikke der ses en streng i EEPROM, så sættes strengen til sin standard værdi.&lt;br /&gt;
&lt;br /&gt;
===Lagring af en ny streng===&lt;br /&gt;
Hvis der indtastes en ny streng, så skiftes den eksisterende visning ud med den nye modtagne streng.&lt;br /&gt;
&lt;br /&gt;
På dette tidspunkt gemmes den nye strang og antallet af karakterer så også i EEPROM. Dette fører til følgende kode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (ch == 13) {   // Ved linje slut - CR - gemmes den&lt;br /&gt;
      EEPROM.write(0, modtPtr);  // Gem antallet af karakterer i EEPROM&lt;br /&gt;
      for (int n = 0; n &amp;lt; modtPtr; n++) {&lt;br /&gt;
        streng[n] = modtStreng[n];&lt;br /&gt;
        EEPROM.write(n+1, streng[n]);  // Gem strengens karakter i EEPROM&lt;br /&gt;
      }&lt;br /&gt;
      // Antallet i linjen registreres og der gøres klar til modtagelse af ny linje&lt;br /&gt;
      strAntal = modtPtr;&lt;br /&gt;
      modtPtr = 0;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test af lagring i EEPROM===&lt;br /&gt;
Det at der ikke læses noget tilfældigt i EEPROM, hvis teksten er tom er testet i første hug, derefter kunne EEPROM ikke slettes (andet end hvis der blev lagt andet indhold i af et andet program), mem det ser ud til at fungere på en frisk Arduino, så standard-teksten kommer frfem.&lt;br /&gt;
&lt;br /&gt;
Efter at der er lagt en ny tekst ind i EEPROM vil det være denne tekst den starter med efter enhver reset (testet med Serial Monitor start, Reset-knap og power off). Programmerer med koden ned igen bliver EEPROM&amp;#039;en ikke overskrevet, så der kommer den sidst gemte tekst fra EEPROM&amp;#039;en frem igen.&lt;br /&gt;
&lt;br /&gt;
Lagring i EEPROM må siges at fungere.&lt;br /&gt;
&lt;br /&gt;
==Referencer==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Arduino-Modul-Oversigt}}&lt;br /&gt;
[[Kategori:arduino Moduler]]&lt;/div&gt;</summary>
		<author><name>htx_&gt;Bar</name></author>
	</entry>
</feed>