RGB LED Matrix met Raspberry pi Zero W

Dit artikel legt uit, hoe een LED matrix te maken, aangestuurd door een Raspberry Pi Zero in combinatie met Python code.

Wat heb je nodig?

  • LED Matrix 64×32 of 32×32
  • Raspberry Pi Zero Wireless
  • Voeding voor Pi Zero (optioneel) (een goede telefoonlader is afdoende)
  • Breadboard kabels (female-female)
  • 5 volt voeding (minimaal 3A)
  • Soldeerbout en soldeertin
  • krimpkous (optioneel)
  • Micro SD-kaart (minimaal 8GB)

Prepareren Raspberry Pi Zero.

De Raspberry Pi heeft een besturingssysteem nodig, dat zullen we eerst moeten downloaden op https://www.raspberrypi.org/downloads/raspbian/ we kiezen hier voor het “lite” image, dus zonder desktop. De Pi zero is niet zo krachtig dus we installeren geen desktop, die hebben we toch niet nodig. Het bestand wat we downloaden is van het “.img” type. Het bestand wordt gedownload in ZIP formaat, deze ZIP file moet dus eerst uitgepakt worden met WINZIP of WINRAR. We gebruiken https://www.balena.io/etcher/ om het bestand op de SD-kaart te “branden”, dit duurt een paar minuten. Uiteindelijk hebben we een bootable SD-kaart met twee partities. De “boot” partitie is normaal te lezen. De tweede partitie is niet leesbaar (dat hoort ook zo).

WiFi configureren en “sound” uitzetten en SSH aanzetten.

Voordat we het SD-kaartje in de Pi zero plaatsen zullen we eerst het WiFi gedeelte moeten configureren anders kunnen we de Pi niet meer benaderen. Omdat we voor de aansturing van het Matrix display alle rekenkracht nodig hebben van de Pi, zetten we het geluid uit. Om de Pi op afstand te kunnen configureren moet SSH aangezet worden, later kunnen we dan via Putty commando’s geven op de Pi zonder dat we een beeldscherm en toetsenborden moeten aansluiten.

Aanzetten SSH: De SD-kaart zit nog in onze computer en via de verkenner maken we nu in de “root” van de SD-kaart een bestand aan dat “ssh” heet, dus zonder toevoeging .txt of iets dergelijks.

Wifi configureren: In de root van de SD-kaart maken we een bestand aan met de naam: wpa_supplicant.conf. Het bestand moet de volgende inhoud hebben waar je natuurlijk de ssid en psk vervangt voor je eigen gegevens. Je kunt het stukje van “netwerk” tot ” }” nog een keer opnemen met een tweede netwerk. Bijvoorbeeld thuis en op het werk.

country=NL
  ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
  update_config=1

  network={
      ssid="NETWORK-NAME"
      psk="NETWORK-PASSWORD"
  }

Uitzetten geluid: in de root van de SD-kaart staat een bestand config.txt. zet daar een # voor de geluidsinstellingen zodat deze niet meer opstarten.

Opstarten Raspberry Pi

De SD-kaart kan nu in de Pi geplaatst worden en de Pi kan worden opgestart. Als je alles goed hebt gedaan meldt de Pi zich nu aan op je WiFi netwerk en is zichtbaar in je netwerk. Om erachter te komen welk IP-adres je Pi heeft gekregen van je router, kun je bijvoorbeeld op je router achterhalen wat dit adres is. Op je telefoon kun je de app “Fing” installeren en via Fing achterhalen wat het IP-adres is van je Pi Zero.

PUTTY

Om via SSH connectie te maken met je Pi, kun je Putty gratis downloaden en installeren op je PC. Om verbinding te maken met je Pi, vul je bij “hostname” het IP-adres van je Pi in, het poortnummer is 22 en “connection type” is SSH. Accepteer het aangeboden certificaat. Met een beetje geluk krijg je nu het aanlogscherm van de Pi aangeboden en zul je moeten aanloggen op de Pi. default username = pi, default password = raspberry.

Installeren Python en benodigde Libraries

Nu je op de command prompt zit van de Pi kunnen we de benodigde software installeren.

Python en toepassingen installeren: Type het volgende commando: sudo apt-get install -y –force-yes python2.7-dev python-pillow python3-dev python3-pillow libgraphicsmagick++-dev libwebp-dev

GIT installeren: Type het volgende commando:

sudo apt-get install git
git clone https://github.com/hzeller/rpi-rgb-led-matrix.git

compile python:

cd rpi-rgb-led-matrix
make all
make build-python
make install-python

Bedraden Raspberry pi Zero

Bij het gebruik van 1 Matrix, hoef je alleen de ? aan te sluiten. Pin 10 dient niet aangesloten te worden. De Pin nummer staan voor de connecties op de Pi

[1]=?, [2]=? and [3]=? ; signals that go to all chains have all icons.

Connection Pin Pin Connection
1 2
[3] G1 3 4
[3] B1 5 6 GND ???
??? strobe 7 8 [3] R1 ?
9 10 E ??? (for 64 row matrix, 1:32)
??? clock 11 12 OE- ???
[1] G1 13 14
??? A 15 16 B ???
17 18 C ???
[1] B2 19 20
[1] G2 21 22 D ??? (for 32 row matrix, 1:16)
[1] R1 23 24 [1] R2 ?
25 26 [1] B1 ?
27 28
[2] G1 29 30
[2] B1 31 32 [2] R1 ?
[2] G2 33 34
[2] R2 35 36 [3] G2 ?
?[3] R2 37 38 [2] B2 ?
39 40 [3] B2 ?

Bron: https://github.com/hzeller/rpi-rgb-led-matrix/blob/master/wiring.md

Pin nummers Pi Zero

Connectie nummers HUB75 connector op de LED matrix. Dit zijn de connectie van de input connector.

Verbind volgens het bovenstaande schema de Pi zero met de LED-matrix. Sluit de 5 volt (minimaal 3A) voeding aan op de connectors van de LED-matrix. Je kunt de Pi Zero nu ook voeden vanaf deze powersupply door de plus en de min af te takken van de 5V 3A voeding en aan te sluiten op PIN 2 en 14 van de pi zero.

Je eerste programma starten

We hebben in de bovenstaande stappen niet alleen gezorgd dat we de LED-matrix kunnen aansturen met met Python, we kunnen dit ook doen met C++. Python is makkelijker te begrijpen dan C++ maar dit heeft ook een prijs. Python is een stuk langzamer. Laten we daarom eerst maar eens wat C++ code uitvoeren. Via Putty bladeren we naar /home/pi/rpi-rgb-led-matrix/examples-api-use/. Daar staat een Demo programma wat we kunnen uitvoeren. Tik in op de prompt: sudo ./demo -D 9 –led-cols=64 –led-rows=32 en geef een “enter” Als je alles goed hebt gedaan zie je nu een “volume bar” verschijnen op de Matrix. “D9” staat voor het nummer van de Demo, probeer ook maar eens een ander nummer. “–led-cols” staat voor het aantal kolommen van je matrix en “–led-rows” vanzelfsprekend voor het aantal rijen van je LED-matrix.

Mogelijkheden DEMO

sudo ./demo
usage: ./demo -D [optional parameter]
Options:
-D : Always needs to be set
-t : Run for these number of seconds, then exit.
–led-gpio-mapping= : Name of GPIO mapping used. Default “regular”
–led-rows= : Panel rows. Typically 8, 16, 32 or 64. (Default: 32).
–led-cols= : Panel columns. Typically 32 or 64. (Default: 32).
–led-chain= : Number of daisy-chained panels. (Default: 1).
–led-parallel= : Parallel chains. range=1..3 (Default: 1).
–led-multiplexing=<0..10> : Mux type: 0=direct; 1=Stripe; 2=Checkered; 3=Spiral; 4=ZStripe; 5=ZnMirrorZStripe; 6=coreman; 7=Kaler2Scan; 8=ZStripeUneven; 9=P10-128×4-Z; 10=QiangLiQ8 (Default: 0)
–led-pixel-mapper : Semicolon-separated list of pixel-mappers to arrange pixels.
Optional params after a colon e.g. “U-mapper;Rotate:90”
Available: “Mirror”, “Rotate”, “U-mapper”. Default: “”
–led-pwm-bits=<1..11> : PWM bits (Default: 11).
–led-brightness=: Brightness in percent (Default: 100).
–led-scan-mode=<0..1> : 0 = progressive; 1 = interlaced (Default: 0).
–led-row-addr-type=<0..3>: 0 = default; 1 = AB-addressed panels; 2 = direct row select; 3 = ABC-addressed panels (experimental) (Default: 0).
–led-show-refresh : Show refresh rate.
–led-inverse : Switch if your matrix has inverse colors on.
–led-rgb-sequence : Switch if your matrix has led colors swapped (Default: “RGB”)
–led-pwm-lsb-nanoseconds : PWM Nanoseconds for LSB (Default: 130)
–led-pwm-dither-bits=<0..2> : Time dithering of lower bits (Default: 0)
–led-no-hardware-pulse : Don’t use hardware pin-pulse generation.
–led-panel-type= : Needed to initialize special panels. Supported: ‘FM6126A’
–led-slowdown-gpio=<0..4>: Slowdown GPIO. Needed for faster Pis/slower panels (Default: 1).
–led-daemon : Make the process run in the background as daemon.
–led-no-drop-privs : Don’t drop privileges from ‘root’ after initializing the hardware.
Demos, choosen with -D
0 – some rotating square
1 – forward scrolling an image (-m )
2 – backward scrolling an image (-m )
3 – test image: a square
4 – Pulsing color
5 – Grayscale Block
6 – Abelian sandpile model (-m )
7 – Conway’s game of life (-m )
8 – Langton’s ant (-m )
9 – Volume bars (-m )
10 – Evolution of color (-m )
11 – Brightness pulse generator
Example:
./demo -t 10 -D 1 runtext.ppm
Scrolls the runtext for 10 seconds

Hoe maak de scrolling tekst van het beginfilmpje

Om te beginnen is de scrolling tekst niet echt tekst maar een Bitmap plaatje (.ppm). Zo’n plaatje kun je maken in Photoshop of bijvoorbeeld het gratis te downloaden programma “the Gimp” (Opensource). Het plaatje van het voorbeeld is 32 pixels hoog (kom overeen met het aantal pixels van de LED-matrix) en 500 pixels lang (dit mag variëren). Het mooiste effect is als de achtergrond van de tekst zwart is. We gaan nu wat Python code bekijken en uitvoeren. Blader (Via Putty) naar: /home/pi//rpi-rgb-led-matrix/bindings/python/samples. We gaan het “image-scroller.py” bestand opstarten maar kijken eerst even in het bestand.

#!/usr/bin/env python
import time
from samplebase import SampleBase
from PIL import Image


class ImageScroller(SampleBase):
    def __init__(self, *args, **kwargs):
        super(ImageScroller, self).__init__(*args, **kwargs)
        self.parser.add_argument("-i", "--image", help="The image to display", default="../../../examples-api-use/Surfing.ppm")

    def run(self):
        if not 'image' in self.__dict__:
            self.image = Image.open(self.args.image).convert('RGB')
        self.image.resize((self.matrix.width, self.matrix.height), Image.ANTIALIAS)

        double_buffer = self.matrix.CreateFrameCanvas()
        img_width, img_height = self.image.size

        # let's scroll
        xpos = 0
        while True:
            xpos += 1
            if (xpos > img_width):
                xpos = 0

            double_buffer.SetImage(self.image, -xpos)
            double_buffer.SetImage(self.image, -xpos + img_width)

            double_buffer = self.matrix.SwapOnVSync(double_buffer)
            time.sleep(0.01)

# Main function
# e.g. call with
#  sudo ./image-scroller.py --chain=4
# if you have a chain of four
if __name__ == "__main__":
    image_scroller = ImageScroller()
    if (not image_scroller.process()):
        image_scroller.print_help()

Laat je niet afschrikken door alle code, we kijken voorlopig alleen naar de regel “../../../examples-api-use/Surfing.ppm”. We zien dat er hier verwezen wordt naar een .ppm bestand in de “examples-api-use” map. We kunnen de plaatjes in elke map plaatsen en hier de verwijzing aanpassen. Door een nieuw .ppm bestand te plaatsen in de ” examples-api-use” map en hier de naam aan te passen kunnen wel elke tekst voorbij laten scrollen die we willen.

Uploaden bestanden naar je Pi Zero.

Om de bestanden (.ppm) van het vorige hoofdstuk op je Pi Zero te krijgen kun je gebruik maken van het gratis te downloaden WinSCP. Vul het IP-adres van je Pi in en maak verbinding, zie plaatje hieronder:

Klik vervolgens op “inloggen”. Aan de linkerkant van het venster zie je de mappen op je PC en aan de rechterkant de mappen op de Pi. Je kunt nu makkelijk bestanden kopiëren van je PC naar de Pi en andersom.

News rss Scroller

Nog een aardig toepassing van de LED-matrix is het maken van een News rss Scroller. Om dit te bewerkstelligen moet je twee Python scripts en een lettertype plaatsen in de /Python/samples directory. Hieronder de twee scripts. De eerste moet je opslaan als rss.py en de tweede als scroll.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# By : Ramin Sangesari
# from samplebase import SampleBase
import datetime
import time
import argparse
import sys
import os
import random
import feedparser
import hashlib
from glob import glob
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import urllib2
from bs4 import BeautifulSoup
from logging import getLogger, StreamHandler, DEBUG
logger = getLogger(__name__)
handler = StreamHandler()
handler.setLevel(DEBUG)
logger.setLevel(DEBUG)
logger.addHandler(handler)
logger.propagate = False
sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/..'))
Imgformat = '.ppm'
def isOkToCrawl():
    crawl_interval = 5 #sec.
    crawl_interval_file = "./lastcrawl"
    now = time.time()
    if os.path.isfile(crawl_interval_file):
        if os.stat(crawl_interval_file).st_mtime > now - crawl_interval:
            return False
    
    f = open(crawl_interval_file, 'w')
    f.write(str(now) + "\n")
    f.close()
    return True
	
def getImageFromFile(path):
    image = Image.open(path).convert('RGB')
    return image
	
def saveImgFromText(text, imgdir, fontsize):
    path = os.path.abspath(os.path.dirname(__file__))
    print path
    if fontsize == 20:
        font  = [ImageFont.truetype(path + '/VERDANA.TTF', fontsize),2]
    color  = [(255,0,255),
             (0,255,255),
             (255,255,0),
             (0,255,0),
             (255,255,255)]
    width, ignore = font[0].getsize(text)
    im = Image.new("RGB", (width + 40, fontsize+40), "black")
    draw = ImageDraw.Draw(im)
    draw.text((0, font[1]), text, random.choice(color), font=font[0])
    imgname = imgdir+"/"+str(fontsize)+str(hashlib.md5(text.encode('utf_8')).hexdigest())+Imgformat
    if not os.path.exists(imgname):
        im.save(imgname)
		
		
def removeOldImg(imgdir):
    #remove ppm files more than 1 days before.
    if not(imgdir=="") and not(imgdir=="/")and not(imgdir=="."): 
        now = time.time()
        for f in os.listdir(imgdir):
            if f[-4:] == '.ppm':
                f = os.path.join(imgdir, f)
                if os.stat(f).st_mtime < now - 0.5 * 86400:
                    if os.path.isfile(f):
                        os.remove(f)
						
						
def getNewsFromFeed():
    news  = []
    url = ['https://www.nu.nl/rss']
    for tg in url:
        fd = feedparser.parse(tg)
        for ent in fd.entries:
            news.append(u"          "+unicode(ent.title))
    return news
	
			
parser = argparse.ArgumentParser()
if isOkToCrawl():
    
    imgdir = os.path.abspath(os.path.dirname(__file__)) + "/newsimg"
    print imgdir
    if not os.path.isdir(imgdir):
        os.mkdir(imgdir)
    #clean up old news
    removeOldImg(imgdir)
    #get from RSS feed
    for text in getNewsFromFeed():
        saveImgFromText(text, imgdir, 20)
else:
    print ("You need to wait for 1min before next crawl.")
#!/usr/bin/env python
# -*- encoding:utf8 -*-
# By: Ramin Sangesari
from samplebase import SampleBase
import time
import argparse
import sys
import os
import random
import feedparser
from PIL import Image
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
from logging import getLogger, StreamHandler, DEBUG
logger = getLogger(__name__)
handler = StreamHandler()
handler.setLevel(DEBUG)
logger.setLevel(DEBUG)
logger.addHandler(handler)
logger.propagate = False
sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/..'))
from rgbmatrix import RGBMatrix, RGBMatrixOptions
def run(image, matrix):
   print("Running...")
   image.resize((matrix.width, matrix.height), Image.ANTIALIAS)
   double_buffer = matrix.CreateFrameCanvas()
   img_width, img_height = image.size
   xpos = 0
   while True:
       xpos += 1
       if (xpos > img_width):
           xpos = 0
           break
       double_buffer.SetImage(image, -xpos)
       double_buffer.SetImage(image, -xpos + img_width)
       double_buffer = matrix.SwapOnVSync(double_buffer)
       time.sleep(0.04)
def prepareMatrix(parser):
   args    = parser.parse_args()
   options = RGBMatrixOptions()
   if args.led_gpio_mapping != None:
     options.hardware_mapping = args.led_gpio_mapping
   options.rows = 32
   options.cols = 64
   options.chain_length =1
   options.parallel = 1
   options.pwm_bits = args.led_pwm_bits
   options.brightness = 50
   options.pwm_lsb_nanoseconds = args.led_pwm_lsb_nanoseconds
   options.multiplexing = args.led_multiplexing
   if args.led_show_refresh:
     options.show_refresh_rate = 1
   if args.led_slowdown_gpio != None:
       options.gpio_slowdown = args.led_slowdown_gpio
   if args.led_no_hardware_pulse:
     options.disable_hardware_pulsing = True
   return RGBMatrix(options = options)
def getImageFromFile(path):
   image = Image.open(path).convert('RGB')
   return image
parser = argparse.ArgumentParser()
parser.add_argument("-r", "--led-rows", action="store", help="Display rows. 16 for 16x32, 32 for 32x32. Default: 32", default=32, type=int)
parser.add_argument("-t", "--led-cols", action="store", help="Display rows. 16 for 16x32, 32 for 32x32. Default: 32", default=32, type=int)
parser.add_argument("-c", "--led-chain", action="store", help="Daisy-chained boards. Default: 1.", default=1, type=int)
parser.add_argument("-P", "--led-parallel", action="store", help="For Plus-models or RPi2: parallel chains. 1..3. Default: 1", default=1, type=int)
parser.add_argument("-p", "--led-pwm-bits", action="store", help="Bits used for PWM. Something between 1..11. Default: 11", default=11, type=int)
parser.add_argument("-b", "--led-brightness", action="store", help="Sets brightness level. Default: 100. Range: 1..100", default=10, type=int)
parser.add_argument("-m", "--led-gpio-mapping", help="Hardware Mapping: regular, adafruit-hat, adafruit-hat-pwm" , choices=['regular', 'adafruit-hat', 'adafruit-hat-pwm'], type=str)
parser.add_argument("--led-scan-mode", action="store", help="Progressive or interlaced scan. 0 Progressive, 1 Interlaced (default)", default=1, choices=range(2), type=int)
parser.add_argument("--led-pwm-lsb-nanoseconds", action="store", help="Base time-unit for the on-time in the lowest significant bit in nanoseconds. Default: 130", default=130, type=int)
parser.add_argument("--led-show-refresh", action="store_true", help="Shows the current refresh rate of the LED panel")
parser.add_argument("--led-slowdown-gpio", action="store", help="Slow down writing to GPIO. Range: 1..100. Default: 1", choices=range(3), type=int)
parser.add_argument("--led-no-hardware-pulse", action="store", help="Don't use hardware pin-pulse generation")
parser.add_argument("--led-multiplexing", action="store", help="Multiplexing type: 0=direct; 1=strip; 2=checker; 3=spiral (Default: 0)", default=0, type=int)
parser.add_argument("-i", "--image", help="The image to display", default="./news.ppm")
imgdir = os.path.abspath(os.path.dirname(__file__)) + "/newsimg"
matrix = prepareMatrix(parser)
if not os.path.isdir(imgdir):
   print("Error: no img to display, no such directory.")
   sys.exit(0)
else:
   while True:
       files = os.listdir(imgdir)
       if len(files)==0:
           print("Warning: no img to display, I am going to wait news to come.")
           time.sleep(5.0)
       else:
           frnd = random.sample(files,len(files))
           for f in frnd:
               if f[-4:] == '.ppm':
                   f = os.path.join(imgdir, f)
                   try:
                       if os.path.exists(f):
                           run(getImageFromFile(f), matrix)
                       else:
                           print("Warning: no such file, next please...")
                   except IOError:
                       print("Warning: no such file, next please...")
                   except KeyboardInterrupt:
                       print("Exiting\n")
                       sys.exit(0)
               else:
                   printf("Warning: Please do not include non-ppm files.")
                   sys.exit(0)

Verdana font download: http://dijkx.com/download/VERDANA.TTF

Om de code uit te voeren tik: sudo python rss.py & sudo python scroll.py. Je kunt deze code ook direct uitvoeren als je Pi opstart. je moet de onderstaande code dan plaatsen in /etc/rc.local net voor het exit 0 commando.

cd /home/pi/rpi-rgb-led-matrix/bindings/python/samples/
sudo python rss.py & sudo python scroll.py

Missende libraries en dergelijke

Om missende libraries, modules en dergelijke te installeren kan het noodzakelijk zijn om het PIP package systeem van Python te installeren op de Pi. Dit doe je door het commando: sudo apt-get install pip.

Om daarna packages te installeren met pip, tik je in: sudo pip install packagenaam

Bij sommige demo programma’s krijg je een foutmelding als de module “rgbmatrix” geïmporteerd wordt. Zet deze regel (from samplebase import SampleBase) dan voor de regel van de “rgbmatrix” import. Dit zou het probleem moeten oplossen.

Voorbeeld code

Hieronder de (slordige) code die laat zien wat er allemaal mogelijk is met de RGB LED matrix. Met een beetje fantasie kun je echt leuke dingen maken. Het bovenstaande filmpje maakt gebruik van de onderstaande Python code. Je ziet dat we eigenlijk geen tekst scrollen maar eerst plaatjes maken van de tekst (.ppm) en deze plaatjes worden dan getoond.

#!/usr/bin/env python
# PIL Image module (create or load images) is wordt hier uitgelegd:
# http://effbot.org/imagingbook/image.htm
# PIL ImageDraw module (draw shapes to images) wordt hier uitgelegd:
# http://effbot.org/imagingbook/imagedraw.htm
#code gemaakt door Dijkx kijk op www.dijkx.com voor uitleg

#importeren benodigde libraries
from samplebase import SampleBase
from PIL import Image
from PIL import ImageDraw
import time
from rgbmatrix import RGBMatrix, RGBMatrixOptions
from PIL import ImageFont
import random
import os

# configuratie van de Matrix
options = RGBMatrixOptions()
options.rows = 32
options.cols = 64
options.chain_length = 1
options.parallel = 1
options.hardware_mapping = 'regular'  

matrix = RGBMatrix(options = options)

kleur1= random.randrange(0,255)		#bepaal een willekeurige kleur tussen 0 en 255
kleur2= random.randrange(0,255)
kleur3= random.randrange(0,255)

textrandom = ['Do not look behind you ', 'do not look behind you ', 'stand on one leg ', 'Close your eyes ', 'say cheese ', 'Stick out your tongue ', 'Say hello ', 'stop looking at your phone ', 'put your phone away ', 'skip down the hallway ', 'jump up and down ', 'sit on the floor ', 'turn down your music ', 'take off your hat ', 'stop talking on your phone ', 'go study ','do your homework ', 'do not slouch ', 'stand up straight ','do not swear ', 'do not do drugs ', 'do what you want ', 'relax ', 'go to class ',  'study ',  'do not fail ']

willekeur=random.choice(textrandom) 		#haal een willekeurige zin uit de bovenstaande lijst
willekeur1=random.choice(textrandom) 		




text = ((willekeur , ((kleur3), (kleur1), (kleur2))), ("and ", ((kleur1), (kleur2), (kleur3))), (willekeur1, ((kleur2), (kleur3), (kleur1))))

 
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 22)  #font en fontsize
	
all_text = ""
	
for text_color_pair in text:
	t = text_color_pair[0]
    	all_text = all_text + t
 
print(all_text,"test") 				#print op de prompt alle tekst die naar de matrix gaat.
width, ignore = font.getsize(all_text)		#bepaal de breedte van het plaatje
print(width, "test1") 				#print de breedte van het plaatje op de prompt


 
im = Image.new("RGB", (width + 30, 32), "black") 		#32 is hoogte van plaatje in pixels
draw = ImageDraw.Draw(im)
 
	
x = 0;
	
for text_color_pair in text:
    	t = text_color_pair[0]
    	c = text_color_pair[1]
    	print("t=" + t + " " + str(c) + " " + str(x),"test2")
    	draw.text((x, 0), t, c, font=font)
    	x = x + font.getsize(t)[0]
 
im.save("plaatjes/test.ppm") 			#bewaar het bestand in ppm formaat






#plaatjes laden 
im0 = Image.open("collin.ppm") 
im1 = Image.open("dijkx.ppm")
im2 = Image.open("Surfing.ppm")
im3 = Image.open("plaatjes/test.ppm")
im4 = Image.open("c.ppm") 	#17
im5 = Image.open("o.ppm")	#12
im6 = Image.open("l.ppm")	#6
im7 = Image.open("l2.ppm")	#5
im8 = Image.open("i.ppm")	#7
im9 = Image.open("n.ppm")	#12
im10 = Image.open("kers.ppm")	#22
im11 = Image.open("citroen.ppm")	#20
im12 = Image.open("meloen.ppm")	#19
im13 = Image.open("negative.ppm")
im14 = Image.open("noprice.ppm")

width, ignore = font.getsize(all_text)		#bepaal de breedte van het plaatje


# de plaatjes laten scrollen

#slotmachine

#fruit1= random.randrange( im10, im11, im12 )	#bepaal een willekeurige kleur tussen 0 en 255
#fruit2= random.randrange( im10, im11, im12 )
#fruit3= random.randrange( im10, im11, im12 )


#eerste ring
for n in range(-32, 0):  # kers van boven buitenbeeld naar midden
    matrix.SetImage(im10, 0, n)
    time.sleep(0.001)
#time.sleep(0.1)


for n in range(0, 32):  # kers midden naar beneden buitenbeeld
    matrix.SetImage(im11, 0, n)
    time.sleep(0.001)
#time.sleep(0.1)

for n in range(-32, 0):  # cirtoen van boven buitenbeeld naar midden
    matrix.SetImage(im12, 0, n)
    time.sleep(0.001)
#time.sleep(1)

for n in range(0, 32):  # citroen van midden naar beneden buitenbeeld
    matrix.SetImage(im11, 0, n)
    time.sleep(0.001)
#time.sleep(5)

for n in range(-32, 0):  # meloen van boven buitenbeeld naar midden
    matrix.SetImage(im10, 0, n)
    time.sleep(0.001)
#time.sleep(1)
#einde eerste ring


#tweede ring
for n in range(-32, 0):  # kers van boven buitenbeeld naar midden
    matrix.SetImage(im11, 22, n)
    time.sleep(0.001)
#time.sleep(0.1)


for n in range(0, 32):  # kers midden naar beneden buitenbeeld
    matrix.SetImage(im12, 22, n)
    time.sleep(0.001)
#time.sleep(0.1)

for n in range(-32, 0):  # cirtoen van boven buitenbeeld naar midden
    matrix.SetImage(im12, 22, n)
    time.sleep(0.001)
#time.sleep(1)

for n in range(0, 32):  # citroen van midden naar beneden buitenbeeld
    matrix.SetImage(im12, 22, n)
    time.sleep(0.001)
#time.sleep(5)

for n in range(-32, 0):  # meloen van boven buitenbeeld naar midden
    matrix.SetImage(im11, 22, n)
    time.sleep(0.001)
#time.sleep(1)
#einde tweede ring

#begin derde ring
for n in range(-32, 0):  # kers van boven buitenbeeld naar midden
    matrix.SetImage(im10, 39, n)
    time.sleep(0.001)
#time.sleep(0.1)


for n in range(0, 32):  # kers midden naar beneden buitenbeeld
    matrix.SetImage(im11, 39, n)
    time.sleep(0.001)
#time.sleep(0.1)

for n in range(-32, 0):  # cirtoen van boven buitenbeeld naar midden
    matrix.SetImage(im12, 39, n)
    time.sleep(0.001)
#time.sleep(1)

for n in range(0, 32):  # citroen van midden naar beneden buitenbeeld
    matrix.SetImage(im11, 39, n)
    time.sleep(0.001)
#time.sleep(5)

for n in range(-32, 0):  # meloen van boven buitenbeeld naar midden
    matrix.SetImage(im12, 39, n)
    time.sleep(0.001)
#time.sleep(1)


#einde derde ring

time.sleep(3)

matrix.Clear()

#einde test

#smiley negative
for n in range(-32, 0):  # negative van beneden buiten beeld naar midden
    matrix.SetImage(im13, 0, -n)
    time.sleep(0.01)
time.sleep(3)
matrix.Clear()

#smiley negative

matrix.Clear()
#noprice

for n in range(-32, 0):  # noprice van links buiten beeld naar rechts midden 
    matrix.SetImage(im14, n, 0)
    time.sleep(0.001)
matrix.SetImage(im14, 0, 0)
time.sleep(0.5)
matrix.Clear()
time.sleep(0.5)
matrix.SetImage(im14, 0, 0)
time.sleep(0.5)
matrix.Clear()
time.sleep(0.5)
matrix.SetImage(im14, 0, 0)
time.sleep(0.5)
matrix.Clear()
time.sleep(0.5)
matrix.SetImage(im14, 0, 0)
time.sleep(0.5)
matrix.Clear()
time.sleep(0.5)
matrix.SetImage(im14, 0, 0)


time.sleep(2)
matrix.Clear()

#noprice

for n in range(-32, 0):  # Plaatje 1 van boven naar beneden
    matrix.SetImage(im3, 7, n)
    time.sleep(0.01)


matrix.SetImage(im3, 7, 3)	#stuiter code
time.sleep(0.08)   
matrix.SetImage(im3, 6, 0)
time.sleep(0.07)
matrix.SetImage(im3, 5, 2)
time.sleep(0.06)
matrix.SetImage(im3, 4, 0)
time.sleep(0.05)
matrix.SetImage(im3, 3, 1)
time.sleep(0.04)   
matrix.SetImage(im3, 2, 0)
time.sleep(0.03)
matrix.SetImage(im3, 1, 1)
time.sleep(0.02)
matrix.SetImage(im3, 0, 0)

    
time.sleep(0.001)

for n in range(0, im.size[0]):  # im3 van midden scherm naar rechts buiten beeld afhankelijk van de lengte van het plaatje
    matrix.SetImage(im3, -n, 0) # - voor de n is van rechts naar links
    time.sleep(0.02)		#scroll snelheid
matrix.Clear()


for n in range(-32, 0):  # im1 dijkx van links buiten beeld naar rechts midden 
    matrix.SetImage(im1, n, 0)
    time.sleep(0.001)
time.sleep(3)


for n in range(0, 30):  # im1 dijkx van midden naar onder buiten beeld
    matrix.SetImage(im1, 0, n)
    time.sleep(0.01)

for n in range(-32, 0):  # im1 dijkx van boven buitenbeeld naar midden
    matrix.SetImage(im1, 0, n)
    time.sleep(0.01)




for n in range(0, 30):  # im1 dijkx van midden naar onder buiten beeld
    matrix.SetImage(im1, 0, n)
    time.sleep(0.01)

for n in range(-32, 0):  # im1 dijkx van boven buitenbeeld naar midden
    matrix.SetImage(im1, 0, n)
    time.sleep(0.01)

matrix.SetImage(im1, 0, 3)	#stuiter code
time.sleep(0.08)   
matrix.SetImage(im1, 0, 0)
time.sleep(0.07)
matrix.SetImage(im1, 0, 2)
time.sleep(0.06)
matrix.SetImage(im1, 0, 0)
time.sleep(0.05)
matrix.SetImage(im1, 0, 1)
time.sleep(0.04)   
matrix.SetImage(im1, 0, 0)
time.sleep(0.03)
matrix.SetImage(im1, 0, 1)
time.sleep(0.02)
matrix.SetImage(im1, 0, 0)


time.sleep(1)
for n in range(0, 64):  # plaatje 1 van midden naar rechts buiten beeld
    matrix.SetImage(im1, n, 0)
    time.sleep(0.02)

matrix.Clear()

#surfing
for n in range(-32, 0):  # plaatje 2 Surfing van boven buitenbeeld naar midden
    matrix.SetImage(im2, 0, n)
    time.sleep(0.01)

matrix.SetImage(im2, 0, 3)	#stuiter code
time.sleep(0.08)   
matrix.SetImage(im2, 0, 0)
time.sleep(0.07)
matrix.SetImage(im2, 0, 2)
time.sleep(0.06)
matrix.SetImage(im2, 0, 0)
time.sleep(0.05)
matrix.SetImage(im2, 0, 1)
time.sleep(0.04)   
matrix.SetImage(im2, 0, 0)
time.sleep(0.03)
matrix.SetImage(im2, 0, 1)
time.sleep(0.02)
matrix.SetImage(im2, 0, 0)

time.sleep(1)

for n in range(0, im.size[0]+15):  # plaatje 2 surfing van midden naar rechts buiten beeld afhankelijk van lengte im.size[0]
    matrix.SetImage(im2, -n, 0)
    time.sleep(0.01)

matrix.Clear()
#surfing

#collin
for n in range(-32, 0):  # letter c van boven buitenbeeld naar midden
    matrix.SetImage(im4, 0, n)
    time.sleep(0.01)
time.sleep(0.1)

for n in range(-32, 0):  # letter o van boven buitenbeeld naar midden
    matrix.SetImage(im5, 17, n)
    time.sleep(0.01)
time.sleep(0.1)

for n in range(-32, 0):  # letter l van boven buitenbeeld naar midden
    matrix.SetImage(im6, 29, n)
    time.sleep(0.01)
time.sleep(0.1)


for n in range(-32, 0):  # letter l2 van boven buitenbeeld naar midden
    matrix.SetImage(im7, 35, n)
    time.sleep(0.01)
time.sleep(0.1)

for n in range(-32, 0):  # letter i van boven buitenbeeld naar midden
    matrix.SetImage(im8, 40, n)
    time.sleep(0.01)
time.sleep(0.1)

for n in range(-32, 0):  # letter n van boven buitenbeeld naar midden
    matrix.SetImage(im9, 47, n)
    time.sleep(0.01)
time.sleep(1)


for n in range(0,32):  # letter c van midden  naar onder buitenbeeld
    matrix.SetImage(im4, 0, n)
    time.sleep(0.001)
time.sleep(0.1)

for n in range(0,32):  # letter o van midden  naar onder buitenbeeld
    matrix.SetImage(im5, 17, n)
    time.sleep(0.001)
time.sleep(0.1)

for n in range(0,32):  # letter l van midden  naar onder buitenbeeld
    matrix.SetImage(im6, 29, n)
    time.sleep(0.001)
time.sleep(0.1)


for n in range(0,32):  # letter l2 van midden  naar onder buitenbeeld
    matrix.SetImage(im7, 35, n)
    time.sleep(0.001)
time.sleep(0.1)

for n in range(0,32):  # letter i van midden  naar onder buitenbeeld
    matrix.SetImage(im8, 40, n)
    time.sleep(0.001)
time.sleep(0.1)

for n in range(0,32):  # letter n van midden  naar onder buitenbeeld

    matrix.SetImage(im9, 47, n)
    time.sleep(0.001)
#collin
time.sleep(5)
matrix.Clear()


##im.size[1]  im.size[0] hier bepaal je de lengte van het plaatje mee lengte en hoogte