Bitmap Daten von SD Card auslesen

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Jetzt lass mal die config rainbow weg, oder setze der Einfachheit auf led_num=1 und dime ein Array of byte. Wie groß kannst du das array anlegen, bis ein out of space kommt?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ohne Config rainbow, geht ein Array mit 650 noch drauf, bei 660 bin ich out of SRAM.



      mitch schrieb:

      Kann es sein, dass hier dein n größer wird als du LED's hast?
      Beim Test eben hatte ich 200 LEDs eingestellt, aber nur 19x gedrückt. N wird daher nicht zu groß.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von R2D2 Bastler ()

    • Noch eine Idee, um einen Überlauf auszuschließen, bevor du was auf Tastendruck ausliest, fülle den stripe mit einer Farbe rb_fill. Wenn das Programm nicht gleich abkackt und du immer noch 10 Farben per Taste füllen kannst, dann muss man den Fehler woanders suchen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ich hab' mal rot, gruen und blau auf 1, 2 und 3 gesetzt und anschließend rb_fill farbe(1) eingetragen. Der fill-Befehl zerstört schon alles im sram. Ich bekomme im Simulator sogar auf der uart infos über Anzahl der files und Größe angezeigt. Es scheint das Programm im Delirium zu sein.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ja, hab den SWStack auf 40 gestellt und wollte gerade anfangen, die Log Files zu ertellen. Dann noch schnell rb_fill testen und dann a_32_d623ea7e a_32_d623ea7e a_32_d623ea7e a_32_d623ea7e

      Ich bin so ein a_45_132ca9f5 a_45_132ca9f5 a_45_132ca9f5 a_67_e210de67 a_67_e210de67 a_67_e210de67

      Kommt bei mir vorbei, die nächsten trinkende-smileys-211 trinkende-smileys-211 trinkende-smileys-211 gehen auf mich!

      Ich trau mich kaum zu sagen, was ICH falsch gemacht habe. a_71_f9c57bbe
      Ich war so euphorisch, weil das Einlesen zu Beginn so gut geklappt hat, dass ich nach dem Zufügen von der Rainbow-Geschichte die Auswahl des aktiven Channels vergessen hab (und das nachdem ich schon so viele Programme für die Strips bearbeitet habe). So ein verd...... M..t

      Ich hoffe, dass das der einzige Grund war...

      Vielen, vielen Dank für Eure Vorschläge, wahrscheinlich wäre ich ohne sie nie auf meinen eigenen Fehler aufmerksam geworden

      Nette Grüße
      Robert
    • R2D2 Bastler schrieb:

      die Auswahl des aktiven Channels vergessen hab
      tatsächlich, damit fällt das Programm nicht in's Delirium. Prima.
      Malst du dann mit deinem Fliegerchen Bilder in den Himmel?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ich hab' mich ja mal an einem 'Schwenktexter' versucht. Ähnliches könntest du mit deinem Fliegerchen machen und zB. Liebesgrüße am Nachthimmel schreiben.
      Hier mein Versuch im Film
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • tschoeatsch schrieb:

      Malst du dann mit deinem Fliegerchen Bilder in den Himmel?
      Wenn das alles mal funktionieren sollte, dann ja. Die Bilder sind allerdings nur auf langzeitbelichteten Photos zu erkennen. Live für Zuschauer ist nur ein wildes Aufblitzen wahrnehmbar (einfach mal nach Pixelstick googlen). Ob das am Ende auch die Arbeit wert ist, mal sehen.
      Morgen gehts weiter, für heute habe ich mich genug blamiert a_71_f9c57bbe

      Nette Grüße
      Robert
    • Schweren Herzens muss ich mein Pixelstick Projekt für Modellflugzeuge zu Grabe tragen. a_446_12de8e52

      Das Programm selbst funktioniert, ist allerdings viiiieeeel zu langsam. Ich hätte nicht gedacht, dass das Auslesen der SD-Karte mit AVR-DOS so lange dauert. Wenn jemand noch einen Tipp hat, wie man die Daten schneller (sehr viel schneller!) von der SD-Karte bekommt, dann lasst es mich bitte wissen.
      Ein Testbild mit 200x200 Pixel dauert ca 14 Sekunden bis es durch ist. Bei einer angenommenen Pixelsticklänge von ca 2 Metern entspricht das einer Bewegungsgeschwindigkeit von gerade mal 14-15cm/sec (so langsam kann ich nicht mal gehen, geschweigeden fliegen). ;(

      Ich habe das Programm von allem Überflüssigem befreit und stell es hier nochmal als "Pixelstick für Langsame" rein.
      Das gewählte Bild läuft hierbei nach einer kurzen Pause immer wieder durch. Eine Helligkeitsregelung habe ich nicht mehr eingebaut. Bilder müssen vor dem Speichern um 90° gedreht, evt gespiegelt und dunkler gespeichert werden, damit diese vom Pixelstick richtig dargestellt werden.
      Wie die C/C++ Programmierer es schafften, nebenbei auch noch LCD Displays und ähnliches zu betreiben, ist mir ein Rätsel. Wer damit fit ist, findet hier sogar eines der fertigen Programme: mrossphoto.com/digital-light-wand/ (für mich nur römische Dörfer).

      BASCOM-Quellcode

      1. 'Pixelstick V1
      2. '-------------------------------------------------------------------------------
      3. '
      4. 'Pinbelegung
      5. 'Belegung der Anschlusspins am Atmega: Siehe auch Config_MMCSD_HC_Arduino_nano.BAS
      6. 'Eckige Klammern [] sind Anschlussbezeichnungen eines Arduino nano
      7. 'Mmc_cs (CS) --> PortB.1 [D9]
      8. 'MISO --> PortB.4 [D12] (Portb.4 = 1 --> pull up on miso)
      9. 'MOSI --> PortB.3 [D11]
      10. 'SCK --> PortB.5 [D13]
      11. 'GND --> GND [GND]
      12. '+5V --> +5V [5V]
      13. '
      14. 'SS --> PortB.2 --> Set SPI-SS to Output and High for Proper work of!
      15. '
      16. '-------------------------------------------------------------------------------
      17. '
      18. '###############################################################################
      19. $regfile = "m328pdef.dat"
      20. $crystal = 16000000
      21. $hwstack = 60
      22. $swstack = 20
      23. $framesize = 100
      24. $baud = 38400
      25. $include "Config_MMCSD_HC_Arduino_nano.bas"
      26. $include "Config_AVR-DOS.BAS"
      27. '###############################################################################
      28. Const Num_leds = 200 'Anzahl LEDs pro Strip
      29. Config Rainbow = 1 , Rb0_len = Num_leds , Rb0_port = Portd , Rb0_pin = 7 ' , Rb1_len = Num_leds , Rb1_port = Portb , Rb1_pin = 1
      30. ' ^ connected to pin x
      31. ' ^------------ connected to portx
      32. ' ^-------------------------- x leds on stripe
      33. ' ^------------------------------------- x channel
      34. Rb_selectchannel 0
      35. Const Num_leds_1 = Num_leds - 1
      36. Dim Farbe(3) As Byte
      37. Rot Alias Farbe(_base)
      38. Gruen Alias Farbe(_base + 1)
      39. Blau Alias Farbe(_base + 2)
      40. Dim M As Byte
      41. Dim N As Byte
      42. Dim Pos As Long 'Pointer
      43. Dim Pic_offset As Word 'Beginn der Bilddaten/RGB-Werte
      44. Dim Pic_hight As Byte 'muss Num_leds entsprechen
      45. Dim Pic_width As Word 'bei Word --> maximale Bildlänge 65535 Pixel
      46. Dim Rgb_value As Byte
      47. Dim Reading_done As Bit
      48. Dim Choose_picture As Byte
      49. Dim Selected_picture As String * 13 'nur max 8.3 Dateinamen z.B. "12345678.bmp"
      50. Dim Column_start As Long 'bei Long --> theoretisch maximale Bildlänge ~ 3,5 Mio Pixel (bei Num_leds=200)
      51. Dim Column_end As Long 'bei Long --> theoretisch maximale Bildlänge ~ 3,5 Mio Pixel (bei Num_leds=200)
      52. Dim Column_width As Word
      53. Dim Column_counter As Word 'bei Word --> maximale Bildlänge 65535 Pixel
      54. ' für SDHC-Card
      55. ' SD-Declarations:
      56. '*******************************************************************************
      57. Dim Btemp1 As Byte
      58. Dim Sd_card_ok As Bit
      59. Dim Files As String * 12
      60. Dim Buffer_address As Dword
      61. Declare Sub Sdcard_initialize()
      62. Declare Sub Sdcard_init_filesystem()
      63. Declare Sub Activate_sdcard()
      64. Declare Sub Deactivate_sdcard()
      65. Declare Sub Read_header()
      66. Declare Sub Datei_lesen()
      67. '*******************************************************************************
      68. Enable Interrupts
      69. '-------------------------------------------------------------------------------
      70. ' Init SD-Card
      71. Call Sdcard_initialize()
      72. '-------------------------------------------------------------------------------
      73. Reading_done = 0
      74. Column_counter = 0
      75. Pic_width = 1
      76. 'Main:
      77. '*******************************************************************************
      78. Do
      79. 'Reading_done = 0 'später setzen bei erneutem Bildwechsel
      80. Choose_picture = 2 'Bild auswählen
      81. Select Case Choose_picture
      82. Case 1 : Selected_picture = "bild_01.bmp"
      83. Case 2 : Selected_picture = "bild_02.bmp"
      84. Case 3 : Selected_picture = "bild_03.bmp"
      85. End Select
      86. If Column_counter < Pic_width Then
      87. Call Datei_lesen
      88. Else
      89. Rb_clearcolors 'am Bildende alle LEDs ausschalten
      90. Rb_send
      91. Wait 2 'und kurz warten und Bild erneut ausgeben
      92. Reading_done = 0
      93. Column_counter = 0
      94. Pic_width = 1
      95. End If
      96. Rb_send
      97. Loop
      98. End
      99. '###############################################################################
      100. 'SD-Card-Routines
      101. 'für SDHC-Card
      102. Sub Activate_sdcard
      103. Call Deactivate_sdcard
      104. Reset Mmc_cs
      105. End Sub
      106. Sub Deactivate_sdcard
      107. Set Mmc_cs
      108. End Sub
      109. Sub Sdcard_initialize
      110. Call Sdcard_init_filesystem
      111. If Btemp1 <> 0 Or Gbdriveerror <> 0 Then
      112. Wait 1
      113. Goto 0
      114. End If
      115. End Sub
      116. Sub Sdcard_init_filesystem
      117. Call Activate_sdcard
      118. If Gbdriveerror = 0 Then
      119. Btemp1 = Initfilesystem(1)
      120. If Btemp1 = 0 Then Sd_card_ok = 1
      121. End If
      122. End Sub
      123. '-------------------------------------------------------------------------------
      124. 'Datei auslesen:
      125. '
      126. '
      127. Sub Datei_lesen()
      128. M = 1
      129. Open Selected_picture For Binary As #20 'hier wird gewähltes Bild geöffnet
      130. If Reading_done = 0 Then Call Read_header() 'beim erstmaligem Aufrufen Header auslesen
      131. Column_end = Column_start + Column_width
      132. For Pos = Column_start To Column_end
      133. Get #20 , Rgb_value , Pos
      134. Select Case M
      135. Case 1 : Blau = Rgb_value
      136. Case 2 : Gruen = Rgb_value
      137. Case 3 : Rot = Rgb_value
      138. Rb_setcolor N , Farbe()
      139. Incr N
      140. End Select
      141. Incr M
      142. If M > 3 Then M = 1
      143. Next Pos
      144. Close #20
      145. N = 0
      146. Column_start = Column_end + 1 'beim nächsten Call wird die nächste Spalte begonnen
      147. Incr Column_counter
      148. End Sub
      149. '-------------------------------------------------------------------------------
      150. 'Bild-Offset, Bildbreite und Bildhöhe auslesen und erste Spaltenparameter berechnen:
      151. 'Höhe und Breite werden hier vertauscht, da sich diese Angaben nicht auf das gespeicherte
      152. 'Bitmap beziehen, sondern auf den Pixelstick (Höhe = Länge des Pixelsticks bzw Anzahl der LEDs)
      153. Sub Read_header()
      154. Pos = 11 '10 bei Arrays und Config Base=0
      155. Get #20 , Pic_offset , Pos
      156. Pic_offset = Pic_offset + 1 'nicht nötig bei Arrays und Config Base=0
      157. Pos = 19 '18 bei Arrays und Config Base=0
      158. Get #20 , Pic_hight , Pos
      159. Pos = 23 '22 bei Arrays und Config Base=0
      160. Get #20 , Pic_width , Pos
      161. Column_start = Pic_offset
      162. Column_width = Pic_hight * 3 '3 Bytes pro LED
      163. Column_width = Column_width - 1
      164. N = 0
      165. Column_counter = 1 'nachdem Lesen des Headers wird mit Spalte 1 begonnen
      166. Reading_done = 1
      167. End Sub
      Alles anzeigen
      Dateien
    • Hi Robert.

      So schnell sollte man die Flinte nicht ins Korn werfen.

      Prüfe doch mal was die lange Zeit verursacht.
      • Ist es das Initialisieren der SD-Card?
      • das Öffnen der Datei
      • das Lesen von Datei
      • das Schließen der Datei
      • Der Header einlesen
      Ich bin sicher, dass da noch mehr geht als 14 Sekunden für ein Bild.

      Kannst ja die Zeiten der einzelnen Schritte messen und seriell ausgeben lassen.
      Loggen nicht vergessen und hier einstellen.
      Kaum macht man es richtig - und schon geht's!
    • Hi Mitch,

      schnell aufgegeben hab ich nicht (saß die halbe Nacht und heute den ganzen Tag dran). Das Problem ist, dass es nicht nur ein "bischen" an der Zeit fehlt, sondern ganz gewaltig. Selbst bei einer mäßigen Fluggeschwindigkeit von 25-30 kmh müsste der Code 5x so schnell abgearbeitet werden.
      Ich kann aber gerne nochmal testen, wie lange die einzelnen Schritte dauern. Das Initialisiern der SD-Karte ist kein Problem, das geschieht nur einmal zu Beginn. Auch das Lesen des Headers tut nicht wirklich weh, da dieser nur einmal pro Bildaufruf abgefragt wird.
      Die reine Datenausgabe an die LEDs braucht bei einem 200x200 Pixel Bild etwas über 1,2 Sekunden (wenn ich mich nicht verrechnet habe).

      Beim Rest guck ich mal, wie ich die einzelnen Zeiten ermitteln kann und melde mich wieder.

      Nette Grüße
      Robert
    • R2D2 Bastler schrieb:

      Das Programm selbst funktioniert, ist allerdings viiiieeeel zu langsam. Ich hätte nicht gedacht, dass das Auslesen der SD-Karte mit AVR-DOS so lange dauert. Wenn jemand noch einen Tipp hat, wie man die Daten schneller (sehr viel schneller!) von der SD-Karte bekommt, dann lasst es mich bitte wissen.
      Also ich würde dem Teil einen SPI-/I2C-SRAM spendieren. Mit einem 128kByte Chip kannst Du schon was bewegen, ist auch ordentlich schnell (kann per SPI direkt mit 20MHz befeuert werden) und kostet <2€.

      Benutze ich als Puffer für kleine (autonome) Webserver mit Sensoren und puffere mit Akku (z.B. am Gewächshaus).

      Die Herausforderung ist "nur" darin zu sehen, einen Teil der Daten geschickt in einem großen Puffer für die Ausgabe
      Aus datenschutzrechtlichen Gründen befindet sich die Kontaktdaten auf der Rückseite dieses Beitrages.
    • Mir fallen an deinem Code verschiedene Sachen auf, die ich (wenns mein Code wäre) erst mal korrigieren würde. Das vermeidet oft unnötige Fehlersuche. Denn diese Auffälligkeiten sind dann schon mal ausgeschlossen.

      Noch eine Frage.
      Hast du an den Include-Dateien
      • Config AVR-DOS.bas und
      • Config MMCSD_Card_HC_Arduino...bas
      irgendwelche Anpassungen gemacht?

      Ich bin überzeugt, dass da irgendwo im Code oder vielleicht auch in der angeschlossenen Hardware der wurm steckt.
      Kaum macht man es richtig - und schon geht's!
    • @R2D2 Bastler schau doch mal, welchen Kontroller du maximal in dein Flieger rein kriegst. Je mehr sram, umso besser, dann könntest du dein Bild vielleicht puffern und aus dem ram laden. Es gibt ja recht kleine breakout-boards, auch für mega2560, oder zur Not ein blankes board/Adapter von dieser Gehäuseform auf Einzelpins, also so Experimentierboards.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • OK, ich hab jetzt Timer1 mit prescale=8 mitlaufen lassen. Damit zählt er nun 2 Takte/us, richtig?
      Dann komme ich auf folgende Ergebnisse:

      223us > Call Read_header()
      5500us > Open Selected_picture For Binary As #20
      71us > Get #20 , Rgb_value , Pos
      18us > Close #20
      1us-6us > Select Case M bis End Select
      7600us > RB_send

      Header lesen passiert nur beim ersten Bildaufruf, daher kein Problem.

      Für ein ganzen Bild (200x200 Pixel) ergibt sich dann:
      Open und close 1x pro Zeile, d.h. (5500us + 18us) x 200 = 1103600us -> 1,1sec
      Get wird pro Pixel 3x ausgeführt 71us x 3 x 200 x 200 = 8520000us -> 8,52 sec
      Select Case wird pro Pixel 3x ausgeführt (2x nur 1us, 1x6us) daher 3us x 200 x 200 = 120000us -> 120ms
      RB_send 1x pro Zeile, d.h 7600us x 200 = 1520000 -> 1,5 sec

      Unter dem Strich betrachtet, dauert das Byte-Sammeln mit über 8 sec pro Bild viel zu lange und das bei einem Bild von nur 200 Pixeln Länge, welches in natura etwa 2 Meter lang wäre.
      Mein Ziel wäre es gewesen, lange Bilder von 20-30 Metern Länge in den Himmel zu malen. Ist daher so nicht zu machen.

      Bei den anderen beiden Dateien hab ich nur die Pins an meinen Nano angepasst.


      Bezüglich Euren anderen Ideen:
      Ich hab bisher fast nur mit Attinys oder dem Nano gearbeitet, daher hab ich nichts anderes hier. Gerne kann ich auch andere Hardware einsetzen, muss nicht unbedingt deine SD-Karte sein, Hauptsache sie ist möglichst klein und leicht wegen dem Modellflug (ne externe Festplatte geht also garnicht :whistling: ).

      Mit so einem SPI-/I2C-SRAM würde das gehen??? Hab sowas noch nie benutzt, lerne aber gerne dazu. Solange ich irgendeine "Stecklösung" finde (damit ich nicht das ganze Modell an den Rechner klemmen muss), nehm ich auch diese.

      Nette Grüße
      Robert