CamJam EduKit 1 – Starter

CamJam EduKit v2 landscape_sm

Contents of CamJam EduKit 1

It contains the following components, all neatly packaged in a project tin:

  • A 400-point breadboard
  • 3 LEDs (Red, Yellow and Green)
  • A button
  • A buzzer
  • Resistors
  • Jumper cables

You will need to provide the following

  • A board to use with the kit:
    • A Raspberry Pi (any version, including the Raspberry Pi Zero) SD card and power supply
    • or a Raspberry Pi Pico (any version – you may need to solder your own header pins) plus 4 additional M-M jumper wires.
  • You can get these boards from many different suppliers, but we recommend using one of the authorised resellers.
  • A keyboard and mouse. (Using a Pi Zero may require a USB hub and/or adapter to allow you to work with it).

Buying CamJam EduKit 1

CamJam EduKit 1 is available to purchase from The Pi Hut.

Download the worksheets

The CamJam EduKit worksheets use the Python programming language with the GPIO Zero library (for the Raspberry Pi) or MicroPython with the picozero library (if you are working with the Raspberry Pi Pico).

For the Regular Raspberry Pi

The following worksheets are suitable for use with Raspberry Pi microcomputers such as the Raspberry Pi 3+, 4 etc. Please make sure to read the instructions carefully for any notes relevant to your particular model.

We also have some un-tested scripts for Scratch available.

For the Raspberry Pi Pico

The following worksheets are suitable for use with Raspberry Pi Pico microcontrollers such as the Pico, Pico W, Pico H etc. A massive Thank You to Simon9933 who did much of the work to convert the worksheets for the Pico.

Please make sure to read the instructions carefully for any notes relevant to your particular model, especially when it comes to updating the Pico’s firmware.

Download everything

You can download all the worksheets and all the code from GitHub by using the following command on the Raspberry Pi:

git clone


All CamJam EduKit worksheets are covered by a Creative Commons licence. CC-BY-NC-SA

The original Word document versions for both the regular Pi and the Pico are available for re-use or translation by contacting us.

Mailing List

Please sign up to our mailing list to get notifications of new and updated worksheets as well as advanced notice of new EduKits.

126 thoughts on “CamJam EduKit 1 – Starter

  1. I’m feeling picky. In worksheet 1, page 2, the code box at the bottom, penultimate line. The comment that describes the comment line could be construed as meaning that the rest of the file (everything after the line) is ignored. Perhaps:

    Comment line: the # and the following part of the line are ignored.

    I’m sure you have a better phrase master available than I am.

  2. Just got my EduKit! In Worksheet 2 – Jumper Wires shouldn’t “Then end with the ‘pin’ will …” be “The end with the ‘pin’ will …”.
    Looking forward to more worksheets.

  3. Hi, Just bought a Raspberry Pi for our son and this kit looks really interesting. Just wondering what it would cost to ship this to Australia?

  4. Am i doing something wrong or is there a issue with worksheet 4 code, when the program is run it does indeed ask which LED you would like to pick and how many times you would like it to blink but following this nothing happens ???

  5. I’m trying to buy two kits but your page shows me: “We don’t ship to Colombia”. I have bought you before and you have shipped me to Colombia. Can you help me?

  6. Hi,
    Great little kit, i bought to play with my 4 year old daughter (she put bits in board and i did the coding), after doing these tutorials we went onto play with scratch GPIO and make some fun games for her to play. Thank you so much for putting this together.

    Thought I would just add that in Worksheet 5 – Button, the image shows the black lead coming from a different pin to all the others. (normally on GND) Obviously a simple thing to fix but something you may wish to update. (Took me a little while to realise why the button wasn’t reading as blindly followed instructions)

  7. Hi Michael, Just finished 3rd worksheet, enjoyed working through them; when will the working traffic light worksheet be ready? & when can we expect further worksheets? Thank you, Liam.

    1. Traffic light worksheet will be ready in the next couple of weeks, possibly in the next week. The next worksheet after that will likely be the last one and will be a collection of suggestions for projects and pointers on how to get started with them. Make sure to sign up for the mailing list to get notification of when the new ones are released.

  8. Great kit, great price & great way of introducing learners to electronics, IO and coding.

    Note – was cheaper to purchase from Amazon with free shipping than from Pi Hut – the £2 shipping for something that cost £5 put me off the purchase from Pihut and delayed my purchase until product was on Amazon.

    Wanted to test that all the components worked – only way to do this was to build and code – guess thats the point – the PDF’s mean’t I couldn’t cut and paste the code – guess thats the point – I needed to ENGAGE with the project and type the code, which lead to obvious coding errors and thus remembering how to debug code !

    Found the change of GPIO pin for button confusing – pin 3 sheet 2 – LED’s and sheet 6 – Buzzer changes to pin 4 Sheet 5 – Button ?

    Here’s to this kit, the pi’s and other bits being in every school kids learning about technology.

        1. I think the main problem is with the shipping company in Poland and not the people there. Poczta polska (default polish provider) is known for low quality service and almost zero chance to receive a package if it’s sent without tracking number. Unfortunately I’m one of the victims of package lost in transport. The_pi_hut (ebay) refunded me all the cost …

  9. I Wonder if something is wrong, the son and i are stucked on getting the led to light up on worksheet two. We have a RPi B+ and RPi A+, have tested on both (with same SD Card) and none of them will turn on the light. If we on the other hand send commands from the terminal (following step 6 in this guide: then the light Works. but not via python.. any ideas what might be wrong ?

    1. I’m not sure what the problem could be. Have you tried doing: sudo apt-get update and then sudo apt-get upgrade ? Maybe it’s got something to do with having an old version of the Python library. Try that and let us know.

      1. Well, we reloaded the sd card with the same noob distribution as before, without doing update/upgrade. Now it works 🙂 also we did not do any localization (dk) except from setting the keyboard to DK layout. I will do an update/upgrade to see if it will keep working, if so then i asume it is the localization that are the trouble maker.

        Beside that, we have now gone through the first set and coded a working trafic light, looking forward to go through edu-kit 2.

        Cheers from DK

  10. Great little kit which I have bought for my Grandaughter to experiment with. My first reaction was that the jumper leads a are all white with the exception of one green one. Whilst I know the colour is not important it may be confusing to someone new to circuits as the worksheets show different colours.

  11. Hiya I’ve typed in the code for the traffic light worksheet all seems perfect but when I run the code it says
    File: “”, line 22
    def SteadyAmber():
    (Def has arrow pointing to the f)
    IndentationError: expected an indented block
    Please help

  12. Hi.. Help.. I am doing something wrong! EDuKit 1 w/s 2 LEDs following the instructions as listed on one line here but as the w/s on separate lines in Python

    Type in the following code: import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(18,GPIO.OUT) GPIO.setup(23,GPIO.OUT) GPIO.setup(24,GPIO.OUT)

    I get a: Runtime Error: No access to /dev/mem. Try running as Root! (attached to the GPIO.setup(18,GPIO.OUT) command).

    How can I rectify this one?

    Sorry to be a pain


    1. Hi Dave. Thanks for the comment – it’s spurred us into action. We’ve updated the web-pages (but not the worksheets themselves yet as we’ve not got time right now) with the licence information. It’s Creative Commons Share Alike (which is what the Foundation uses).

  13. I’ve had a really enjoyable few hours getting to grips with programming my Pi using your excellent kit. The worksheets are really clear and I like how there are explanations as to why we are doing things / what lines of code actually mean. I’ve noticed an error on Worksheet 6 page 4 – there’s an underscore missing between ‘loop’ and ‘count’ on the line to input ‘How many times would you like SOS to loop?’ Also, the resistors described in Worksheet 2 use a 4-band colour coding system, whereas the ones I received had 5 bars (but were correct resistance). Time for Worksheet 7 🙂

  14. Hi Michael,
    Received kits 1 an 2 at the Picademy course in Leeds this week, Excellent resource with superb teaching material well presented, concise and easy for pupils to use. Will definitely use in my teaching. Well done
    Billy Hughes.

  15. Loving the EduKit but curious if anybody else has had issues getting the button in the breadboard in columns E and F? For the life of me the button seems bigger than what can fit into E-F 15, 16.

    1. I find fitting buttons into breadboards to be a real pain. Often I bend the legs, and have to unbend them. It will fit – pub perhaps adjust them a little before trying.

  16. Just wanted a starter kit to take through the first few steps of setting up the PI with electronic components. This is ideal, and a fraction of the price of other kits. The instructions are great and I was using Python to control an LED within 5 mins of opening the box.

  17. Worksheet 5 (Push Button) in the starter kit the GPIO.setup statement should read GPIO.setup(ButtonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    otherwise the initial state of the button is floating and you will get random states when the button is read.

  18. Hi, I am working through the worksheets and have a problem with sheet 6 morse code. when I run the program, it errors on GPIO.setup(PINBuzzer,GPIO.OUT,initial=0) and says “initial is an invalid keyword argument for this function”. Can you help please?

  19. This may be me being dim… In morse code getting ‘line 7 – name error: name ‘GPIO’ is not defined’ checked and rechecked to worksheet appears correct… Help! Coded everything else fine to this point.
    Great kits by the way, I currently have an extremely keen small group of y6 pupils fund raising for kits!

      1. Thank you couldn’t see for looking! using scratch in school for ages, creating own games – needing the next challenge! some really keen year 6 programmers – I’m trying to keep ahead! :/

  20. Hi, this is a fantastic kit at a great price. I found the worksheets very squished! It could be laid out better and explained more thoroughly. I found following where each item goes on the breadboard really hard to follow but I did get there in the end. I’m terrified of blowing a bulb/pi so any tips on what not to do would be really helpful.

    1. Thanks for the feedback. The Pi is actually quite resilient. As long as you don’t pump 5V into the GPIO pins, you’re unlikely to do any damage. When it comes to bulbs (LEDs), just make sure you use resistors and you’ll be fine.

    2. When you say ‘squished’ do you men that the text could be larger and the lines further apart? Would that make it more readable for children, or is it just a personal preference? I want to make it as accessible as I can.

  21. Hi, just getting into Raspberry Pi and decided to give this kit a try and it’s great. Have been working my way though them and beginning to get an understanding of it all works, or at least i thought i was…

    The Advanced Challenge on Worksheet 6, I’ve brought in the buzzer used the code from worksheet 5 but don’t have any clue on how the get the button to switch on the buzzer. Any hints?

    1. The buzzer and button are not connected electronically. You need to write the code that detects the button, and then turn the LED on. Taking the button worksheet as an example, instead of printing anything to the screen, replace the print commend with the code to turn the LED on.

  22. I have written all the text for worksheet 2,it has been checked against the correct code and the picture and i cant run the file can someone give me instructions on the easiest way to run the file

  23. Just completed Worksheet 7 and wanted to cross check your code vs mine, in there is a slight error when using the pedestrian lights on line 66. Has ‘Low’ instead of LOW’.

    An easy fix but just thought i’d let you guy know.

  24. Hi

    I am workin on the advanced challenge on Worksheet 6, but I’m a bit stuck on how to do a dash for the morse code generator, I have been able to produce the dot when I press the button but I’m not sure how to differentiate between the dot and the longer dash when pressing the button. Hope that makes sense !!!

    Having great fun learning Python and GPIO stuff with this brilliant kit.


  25. Hi Tim

    Thanks for the reply, got it working now following your tip 😉 onto the next challenge.

    Loving these brilliant kits

    Thanks again

  26. Excellent kit, I have worked my way through all the worksheets but am stuck on:
    Worksheet 8, Game 2 – Eat the Orange
    Could someone please give me some advice on how to randomly choose an LED ? (I can only get a random number via random.randint)

  27. Thank you for the amazingly quick reply.
    But how do I reference/link the number with the LEDYellow ?
    Could you direct me to or supply that part of the code ?

    1. Thank You for the code. Finally got the led to flash randomly, indents are so so important to get right !!
      Now need to work out the rest 🙂

        1. Thank You again Tim.
          Is there anyone/anywhere I can send my code to be checked ?
          The reason I am asking is that my code only registers my button being pressed when the amber led is switching off, not when it is illuminated and I am stumped as to why 🙁

    1. #Be gentle with me, I am very new to this 🙂

      import os
      import time
      import random
      import RPi.GPIO as GPIO


      LEDRed = 18
      LEDYellow = 23
      LEDGreen = 24
      ButtonPin = 25

      GPIO.setup(LEDRed, GPIO.OUT)
      GPIO.setup(LEDYellow, GPIO.OUT)
      GPIO.setup(LEDGreen, GPIO.OUT)
      GPIO.setup(ButtonPin, GPIO.IN)

      correct_button = 0

      start = time.time()

      while correct_button <= 10:
      led_choice = random.randint(1,3)
      if led_choice == 1:
      led = LEDRed
      if led_choice == 2:
      led = LEDYellow
      if GPIO.input(ButtonPin) == False:
      correct_button = correct_button + 1
      if led_choice == 3:
      led = LEDGreen

      GPIO.output(led, GPIO.HIGH)
      GPIO.output(led, GPIO.LOW)

      end = time.time()

      time_taken = end – start
      time_taken = str(time_taken)

      print("Time taken in seconds is " + time_taken)


    1. import os
      import time
      import random
      import RPi.GPIO as GPIO


      LEDRed = 18
      LEDYellow = 23
      LEDGreen = 24
      ButtonPin = 25

      GPIO.setup(LEDRed, GPIO.OUT)
      GPIO.setup(LEDYellow, GPIO.OUT)
      GPIO.setup(LEDGreen, GPIO.OUT)
      GPIO.setup(ButtonPin, GPIO.IN)

      correct_button = 0

      start = time.time()

      while correct_button <= 10:
      led_choice = random.randint(1,3)
      if led_choice == 1:
      led = LEDRed
      if led_choice == 2:
      led = LEDYellow
      if GPIO.input(ButtonPin) == False:
      correct_button = correct_button + 1
      if led_choice == 3:
      led = LEDGreen

      GPIO.output(led, GPIO.HIGH)
      GPIO.output(led, GPIO.LOW)

      end = time.time()

      time_taken = end – start
      time_taken = str(time_taken)

      print("Time taken in seconds is " + time_taken)


  28. I’m unable to access your dropbox. Could be the firewall here. You might try .

    But I’m going to guess that your button checker if is withing the body of the yellow if. That little chain of four if statemes inside the while, each “if” should have exactly the same indentation as the other “if” lines, and that should be more indentation than the “while” line (which I expect, correctly, has no indentation).

    And on general principles, in case nobody has warned you, be sure that all of your indentation is done with space characters, that is, there should be no tab characters in your file.

      1. But isn’t that what I am trying to achieve “…if the player presses the button while the amber LED is lit, they get a point…”

  29. OK, I’m caught up. Yes, that’s a good try for the code.

    The issue you are seeing is because almost all the time is spent in the time.sleep(). 0.2 seconds is a long time compared to how long it takes the rest of the code to run. Your button is only polled at those exciting instants when sleep() ends, before the next sleep. So you must be holding the button at the time of the 5 Hz tick for it to be seen.

    I take it that you want to recognize the button if it is “tapped” during yellow, even if the tap ends before the 0.2 seconds does.

    There are a few of ways around this, depending on things that I don’t know about the gpio hardware. One possibility is to use an input that can be configured as the clock input of a counter. You clear the counter is software before the sleep, and if, after the sleep, it is non-zero, and led choice is yellow, you add a point. If the pin can cause an interrupt, then your interrupt service routine can set a variable to True, where you make if False before the sleep and check it after the sleep, like the counter. Both of these will require extended study, and may or may not be applicable in RPI (I really should go review the hardware docs again). So I offer a software only approach:

    Poll the switch much more often. In order to still have LED changes only occur on 0.2 second “ticks”, you can use nested loops. for example, using a sleep of 0.001 (much harder to get your finger on and back off of the button in a millisecond), and have the inner loop run 200 times before the outer loop gets to run again. (See “for” statement and “xrange()” function in the python docs.) Most of your code, with the changed sleep, goes in the inner loop..The outer loop gets the randint, sets a flag variable to False, runs the inner loop, and after the inner loop, but still in the outer one, check if the flag is set, and if so, award a point. Your button checking code inside the yellow “if” sets the flag to True instead of awarding the point (you wouldn’t want to award multiple points for a single yellow).

    1. Wow, thank you, but that seems way over my head at this stage 🙁
      Is it possible to put what you are explaining in code form so I can visually see what you mean ?

  30. Cheers Michael, that fixed the NameError.

    The code itself doesnt seem to fix my issue though. Putting a sleep of 0.001 makes it impossible to have enough time to press the button (whole point of the game) and the range command doesnt seem to have fixed my problem, which is not registering a point if the button is pressed when the amber LED is lit 🙁

    1. First, yes, if you are using python 3.x, you must use range. In python 2, if you used range, then every time it was called (5 times a second) , a list of 200 elements would be created, wasting memory, which is why python 2 also has xrange (study generators some time).

      Second, nothing requires you to push a button in a millisecond. If the button is pressed (the GPIO pin is low, returning False) at the end of any of the 200 delays of 1 millisecond, when yellow is lit, the if that interrogates the button pin will set button_seen to True, and it will stay True until the for loop expires, because seeing the button as not pushed (GPIO test is True, thus not equal to False), doesn’t do anything to button_seen.

      If it’s not working, then I’m not seeing why. Does it still look like color changes happen every 0.2 seconds?

          1. Sorry about that. It’s called using an uninitialized variable. Because figuring out the led from the led_choice is interleaved with the button testing code it’s a bit messy to fix. So I figured that I might as well introduce some additional python techniques at the same time.

            Maybe: will work. Even if it does, let me know if you have questions about the changes. If you like you can use the letter icon in the pastebin, or if you think they are of general interest, you can certainly ask here.

          2. Assuming that last pastebin worked, and you understand it, and you want to extend your python skills, you might want explore:
            1. Changing line 33 to “led = random.choice(LEDs)”
            2. Changing lines 38 and 39 to one line: “button_seen |= not GPIO.input(ButtonPin)”
            3. It’s going to be really close here, such that you shouldn’t notice, but doing sleep(0.001) and some code 200 times won’t necessarily take exactly 0.2 seconds, making yellow slightly longer than the others. An alternate approach which should be closer is to, just before the “for” statement, do something like “til = time.time() + STATE_INTERVAL”, and then replace the “for” line with “while til > time.time()”. It is then no longer necessary to calculate SAMPLE_PER_STATE. This would be more important if there were a lot more code in the for loop., And it’s still not good enough if you were instead using the loop to, for example, generate a musical tone. But it’s a useful “pattern” to have in you embedded programming bag of tricks.
            4. Note that you can finish quickly by simply holding the button down. The code detects whether it is ever in the pressed state during yellow, not that it became pressed during a yellow. You could enhance your logic to require that the button was not pressed at the beginning of yellow in order for a press during yellow to be scored. If you want, you could also require that the button not be pressed at the end of yellow, requiring press and release during a single yellow. Even fancier, you could require that the button hasn’t been pressed since the last yellow (much bigger code change). Finally, you could change things such that you never get two yellows in a row. All things that you could come back to later if you found them to be of interest.

  31. Michael, am I over thinking this and trying to run before I can walk ?

    (Is my original code “correct” in terms of what you were trying to teach when writing the worksheet ?)

    1. I can’t answer for the worksheet developers, not having been involved. But if you’re learning, and especially if you are looking beyond the original scheme, that is generally desirable. The ultimate goal is to inspire you and help you to develop the skills you need to do neat things with Raspberry Pi.

      So I wouldn’t worry about sticking with the scope, unless you’re separately being graded on your participation.

  32. Thank you Bill for taking the time to help me and I will take your comments on board, I am not being graded by anyone (only myself !) 🙂

    1. Bill, no I am afraid it didn’t work, i got:
      TypeError: ‘float’ object cannot be interpreted as an integer.
      I have moved onto the Edukit 2.

  33. Excuse my ignorance:
    Why can not I run .py files in command line?
    I can only run them from Python 3 by pressing F5.
    I would appreciate some clarification.
    Thanks in advance

      1. 227/5000
        Incredible, thank you very much !:
        I have been able to run and, and finally all codecs.
        I first tested with python3 and finally, with python
        Works fine! And without errors (goblins?)
        Thank you very much!

  34. *nix (including linux, such as raspbian) does not use the file extension to decide how to run a file. Instead it expects the first several bytes of the file to tell it how to run the file (known as the magic number, but see below). In addition a file is not considered for execution unless the appropriate “executable” bit(s) is set for the file.

    But you can run any .py (or .pyc) file from the command line by proceeding it with “python”, e.g.;

    $ python

    But even then you need an

    if __name__ == ‘__main__’:

    clause in the file if it’s going to do anything (other than report any syntax errors that you may have in the file).

    Now on to running it without saying “python”:

    One of the meaning full sequences of bytes at the beginning of a command line is for the first line to contain


    That number sign, exclamation point (also known as pound bang, or even she-bang) is a “magic number” that the kernel recognizes. It means that the rest of the line is the path to an interpreter to run on this file. Yes, python counts as an interpreter. And python, like most interpreters, ignores lines that begin with #, so python isn’t confused by the line.

    One last step.

    If you do

    $ ls -l

    The list will include a run of ten characters that are, ignoring the first character, hyphen, r, w, or x (or in rare circumstances s or t). These three groups of three characters each give the “permissions” that each of three groups of users have. The first group is for the owner (also shown in the ls -l output). The second is for people in the group of the file (as listed). The final group is everyone else. An r means that bunch can read the file. w means they can write it. These are probably the only two letters that has, for any group. The x, which I expect is missing from, means that they can execute it. The kernel won’t even bother to check for a magic number if the file isn’t “executable” by the user trying to do it (you). It will just refuse. So do

    $ chmod a+x

    Which means add the x-icute permission to a-ll users.

    Now you can just say or at the very least (if “.” isn’t in your PATH) ./foo.pyg

    1. All correct here! But we’re trying to keep things simple in the worksheets, so will not be adding this ‘complication’ (although a very nice one).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.