“Invent Your Own Computer Games with Python” is a free book that teaches you how to program in the Python programming language. Each chapter gives you the complete source code for a new game, and then teaches the programming concepts from the example.
“Invent with Python” was written to be understandable by kids as young as 10 to 12 years old, although it is great for anyone of any age who has never programmed before.
This second edition has revised and expanded content, including using the Pygame library to make games with graphics, animation, and sound.
You can buy it or read/download it online CC version.
If you have a lot of button inputs for a project, keeping track of them (whether they’re pressed, just pressed or just released) and debouncing can get a bit hairy. here is some sample code that will keep track of as many buttons as you’d like. The example shows 6. To change the pins or number of buttons, just put them in the array called “buttons” and the rest of the code will automatically adjust. (The code is in Arduino-ese but its pretty much just straight up C)
Enjoy!
#define DEBOUNCE 10 // button debouncer, how many ms to debounce, 5+ ms is usually plenty
// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {14, 15, 16, 17, 18, 19}; // the analog 0-5 pins are also known as 14-19
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'currently pressed'
byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
void setup() {
byte i;
// set up serial port
Serial.begin(9600);
Serial.print("Button checker with ");
Serial.print(NUMBUTTONS, DEC);
Serial.println(" buttons");
// pin13 LED
pinMode(13, OUTPUT);
// Make input & enable pull-up resistors on switch pins
for (i=0; i< NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT);
digitalWrite(buttons[i], HIGH);
}
}
void check_switches()
{
static byte previousstate[NUMBUTTONS];
static byte currentstate[NUMBUTTONS];
static long lasttime;
byte index;
if (millis() < lasttime) {
// we wrapped around, lets just try again
lasttime = millis();
}
if ((lasttime + DEBOUNCE) > millis()) {
// not enough time has passed to debounce
return;
}
// ok we have waited DEBOUNCE milliseconds, lets reset the timer
lasttime = millis();
for (index = 0; index < NUMBUTTONS; index++) {
justpressed[index] = 0; // when we start, we clear out the "just" indicators
justreleased[index] = 0;
currentstate[index] = digitalRead(buttons[index]); // read the button
/*
Serial.print(index, DEC);
Serial.print(": cstate=");
Serial.print(currentstate[index], DEC);
Serial.print(", pstate=");
Serial.print(previousstate[index], DEC);
Serial.print(", press=");
*/
if (currentstate[index] == previousstate[index]) {
if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
// just pressed
justpressed[index] = 1;
}
else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
// just released
justreleased[index] = 1;
}
pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
}
//Serial.println(pressed[index], DEC);
previousstate[index] = currentstate[index]; // keep a running tally of the buttons
}
}
void loop() {
check_switches(); // when we check the switches we'll get the current state
for (byte i = 0; i < NUMBUTTONS; i++) {
if (justpressed[i]) {
Serial.print(i, DEC);
Serial.println(" Just pressed");
// remember, check_switches() will CLEAR the 'just pressed' flag
}
if (justreleased[i]) {
Serial.print(i, DEC);
Serial.println(" Just released");
// remember, check_switches() will CLEAR the 'just pressed' flag
}
if (pressed[i]) {
Serial.print(i, DEC);
Serial.println(" pressed");
// is the button pressed down at this moment
}
}
}
if you want, you can even run the button checker in the background, which can make for a very easy interface. Remember that you’ll need to clear “just pressed”, etc. after checking or it will be “stuck” on
#define DEBOUNCE 10 // button debouncer, how many ms to debounce, 5+ ms is usually plenty
// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {14, 15, 16, 17, 18, 19}; // the analog 0-5 pins are also known as 14-19
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'currently pressed'
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
void setup() {
byte i;
// set up serial port
Serial.begin(9600);
Serial.print("Button checker with ");
Serial.print(NUMBUTTONS, DEC);
Serial.println(" buttons");
// pin13 LED
pinMode(13, OUTPUT);
// Make input & enable pull-up resistors on switch pins
for (i=0; i< NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT);
digitalWrite(buttons[i], HIGH);
}
// Run timer2 interrupt every 15 ms
TCCR2A = 0;
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= 1<<TOIE2;
}
SIGNAL(TIMER2_OVF_vect) {
check_switches();
}
void check_switches()
{
static byte previousstate[NUMBUTTONS];
static byte currentstate[NUMBUTTONS];
static long lasttime;
byte index;
if (millis() < lasttime) {
// we wrapped around, lets just try again
lasttime = millis();
}
if ((lasttime + DEBOUNCE) > millis()) {
// not enough time has passed to debounce
return;
}
// ok we have waited DEBOUNCE milliseconds, lets reset the timer
lasttime = millis();
for (index = 0; index < NUMBUTTONS; index++) {
currentstate[index] = digitalRead(buttons[index]); // read the button
/*
Serial.print(index, DEC);
Serial.print(": cstate=");
Serial.print(currentstate[index], DEC);
Serial.print(", pstate=");
Serial.print(previousstate[index], DEC);
Serial.print(", press=");
*/
if (currentstate[index] == previousstate[index]) {
if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
// just pressed
justpressed[index] = 1;
}
else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
// just released
justreleased[index] = 1;
}
pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
}
//Serial.println(pressed[index], DEC);
previousstate[index] = currentstate[index]; // keep a running tally of the buttons
}
}
void loop() {
for (byte i = 0; i < NUMBUTTONS; i++) {
if (justpressed[i]) {
justpressed[i] = 0;
Serial.print(i, DEC);
Serial.println(" Just pressed");
// remember, check_switches() will CLEAR the 'just pressed' flag
}
if (justreleased[i]) {
justreleased[i] = 0;
Serial.print(i, DEC);
Serial.println(" Just released");
// remember, check_switches() will CLEAR the 'just pressed' flag
}
if (pressed[i]) {
Serial.print(i, DEC);
Serial.println(" pressed");
// is the button pressed down at this moment
}
}
}
If you want to make a clock with an Arduino/Boarduino/AVR, there is a way to hook up a precision 32khz watch crystal
mtbf0 shows you how! pictured above is his LCD clockduino!
Trialex followed up with a really-big-7-segment clock (in the same thread)
I had a bug that caused serial port support to suddenly stop working and there was a corrupt .dmg file so here is a new set of packages with some updates!
Port delay is definable. SpokePOV used to ‘guess’ what the correct delay is but I think it might be wiser to have the user tweak it as necessary
Support for up to 32 banks of memory. What you need so much for I have no idea but hey, its there now!
Windows version now comes with a spiffy installer. Just like Real Software!
Amazon’s S3 (Simple Storage Service) isn’t new, but its certainly gaining traction. Its a wonderful product for people who have a lot of content on their site (images, video, downloads, pdfs) but not a lot of money. Data storage costs $0.15 per GB-Month (prorated), and $0.20 per GB. No minimums, rounded up to the nearest cent.
There are a lot of great providers out there (I use Laughing Squid and highly recommend it) but even LS’s ‘largest’ package is too small for ladyada.net… What to do? Easy: Host all that bulky content at S3, then use mod_rewrite to reroute it over to S3. (You could also do it with php, asp or similar for higher ’security’ but mod_rewrite is lighter and good enough for me)
For example, this image has the url reference “http://www.ladyada.net/images/mintyboost/assemblyv12/inductorusbplace_t.jpg” but if you access that url in your browser, it is automatically rewritten by apache to http://s3.amazonaws.com/ladyadanet_mintyboost/assemblyv12/inductorusbplace_t.jpg
(same with my research pdf, a big pdf that easily accounted for 500M a day of traffic at its peak! http://www.ladyada.net/media/common/thesis.pdf -> http://s3.amazonaws.com/ladyadanet_common/thesis.pdf , S3 doesn’t care what the data is or how its encoded)
Of course mod_rewrite is not necessary, you can always just directly reference s3.amazonaws.com but that makes it harder to move the content around if you decide to eventually go with another service (or if s3 goes away one day!)
OK so, what’s the point and what does this have to do with electronics, eh? Well one of the killer apps of open source and public domain electronics is documentation. That means media. And media storage, backup and transfer is extremely expensive for the everyday person. It becomes increasingly difficult to host a project when one digg-storm or slashdotting makes that ‘free’ webpage account go down.
Edit: I use the Firefox S3 plugin to upload and set the access control on my files.
Are you using S3 or something similar for your projects, kits or documentation? Leave a comment or email! Its always interesting to see what other people are doing in this space.
I finally got around to rewriting the flickrnotes code i wrote to support IE6/7 as well as overlib. Ironically, as a side effect, I had to do this funky opacity thing because in IE you cant have onMouseOver() on an ‘empty’ DIV or SPAN tag unless it has a background color. However, background colors with opacity work just fine.
Hence:
One could always just keep the Opacity 0% and mess with outlines but i kinda got to liking this look.
I fixed some icky problems (in wxMIDI!) and now the MIDIsense software is crosscompiling nicely between Mac and Windows, therefore there is now fast and updated software for both platforms. Rad! Download it now!
If you wanted to try out the MIDIsense hardware but didn’t have a Mac, well I finally finished porting the wxpython code to C++ and its all much faster and more reliable. I also improved the interface and robustness. Try it out and let me know how it goes, available for download from sourceforge
This weekend I stayed indoors because it was insanely cold, and hacked javascript/php to create a php script that allows one to embed flickr photos into webpages and have the notes show up. Like in midisense sensor soldering instructions (mouseover in the assembly pictures). If you want to grab it, its available for download: flickrnotes.txt (rename it php of course) you’ll need php installed, as well as commandline curl (usually /usr/bin/curl) although im sure it could be modifed to use something else. some work has to be done, i intend to one day integrate it with overLIB which makes nice popups. regardless, hooray for notes!