Flip out with this .Net Gadgeteer Flipbook Maker

Description

Today's Hardware Friday post shows us how we can use the .Net Micro Framework and the .Net Gadgeteer to build a simple Flipbook Maker. It shows that if "hardware" scared you in the past that the .Net Gadgeteer is the cure to that fear, that building cool things is nothing to be afraid of now... So start building!

How to Build a Flipbook Maker: Part 1, Part 2, Part 3 (Complete Project Source)

Build your own stop-motion animation tool using .NET Gadgeteer! The Flipbook Maker combines Gadgeteer's intuitive hardware and software construction with a useful enclosure to create a project that will appeal to your inner cartoonist.

image

What You'll Need

This walkthrough uses modules from GHI Electronics' Fez Spider Starter Kit. Other mainboards and modules can be substituted - just check that your modules will work with the sockets on your mainboard. You can quickly determine whether a module will work with a mainboard by matching the module's socket type letter with the socket type letters on each mainboard socket.

Hardware Modules Used:

  • Mainboard
  • Camera Module
  • Potentiometer Module
  • Button Module
  • SD Card Module (plus an SD card - check your module to determine its card size and capacity requirements)
  • USBClient power module

You'll also need a Gadgeteer development environment. Check out this guide which describes how to set that up.

Finally, if you want to assemble your Flipbook Maker as pictured here, you'll need to create an enclosure for it. We'll talk about fabrication options in a later post - including stuff you can do yourself and services you can use to have the case constructed for you.

  • Step 1: Connect the Modules
  • Step 2: Starting the Software

Part 2

In Part 1, we assembled the hardware and created the event handlers for the Flipbook Maker. Now let's flesh out the software foundation and create a state machine to manage the Flipbook Maker's behavior.

  • Storing Images
  • Flipbook Maker Playback States
  • Implementing the Playback Timer
  • Taking Pictures
  • Implementing the Potentiometer Timer
  • The Flipbook Maker to So Far and What's Next

Part 3

Happy New Year! The Gadgeteer team is back from the holidays and we'll conclude the Flipbook Maker series this week. In Part 1 and Part 2 we assembled the hardware and built the basic software architecture. This post covers using WPF to create a menuing system for the touchscreen display. This will provide the remaining user controls - saving the movie to the SD card, deleting a frame, etc. It will also provide visual cues like frame number and playback status.

  • Adding Resource Images and Fonts to the Project
  • Setting Up the Display
  • A Note on Implementing Lightweight Touch Buttons in Gadgeteer
  • The Touch Event Handlers
  • The Home Stretch: Saving the Movie

I think one of the cooler things about .Net Gadgeteer is the development environment. Even if you don't have the hardware (which I don't) you can still install the SDK's (see this guide) and check out the hardware design and associated code. There's no .Net Gadgeteer emulator that I am aware of, so to run the code you'll need the hardware, but still...

Here's the Solution open on my system;

SNAGHTML1455c5d8

Some snips of code, though I recommend you check out the three different posts as there's more snips there, with assoicated context...

// This method is run when the mainboard is powered up or reset.   
  void ProgramStarted()
  {
      // Set up event handlers for modules
      button.ButtonPressed += new GTM.GHIElectronics.Button.ButtonEventHandler(button_ButtonPressed);
      camera.BitmapStreamed += new GTM.GHIElectronics.Camera.BitmapStreamedEventHandler(camera_BitmapStreamed);

      sdCard.SDCardMounted += new SDCard.SDCardMountedEventHandler(sdCard_SDCardMounted);
      sdCard.SDCardUnmounted += new GTM.GHIElectronics.SDCard.SDCardUnmountedEventHandler(sdCard_SDCardUnmounted);

      SetupDisplay();

      // Set up event handlers for timers, and start timers running
      playbackTimer.Tick += new GT.Timer.TickEventHandler(playbackTimer_Tick);
      playbackTimer.Start();

      potentiometerCheckTimer.Tick += new Gadgeteer.Timer.TickEventHandler(potentiometerCheckTimer_Tick);
      potentiometerCheckTimer.Start();

      // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
      Debug.Print("Program Started");
  }

void button_ButtonPressed(GTM.GHIElectronics.Button sender, GTM.GHIElectronics.Button.ButtonState state)
   {
       if (!camera.CameraReady) return;

       if (frames.Count <= MAXIMUM_FRAMES)
       {
           if (playbackTimer.IsRunning) playbackTimer.Stop();
           if (potentiometerCheckTimer.IsRunning) potentiometerCheckTimer.Stop();
           currentFrame++;
           currentMode = PlaybackMode.Recording;
           cameraImage.Bitmap = new Bitmap((int)display.Width, (int)display.Height); // Give the camera and screen a new bitmap to stream to.
           camera.StartStreamingBitmaps(cameraImage.Bitmap);
       }

   }

   Image icon;
   Text frameNumber;
   Canvas canvas;
   Window mainWindow;

   ArrayList buttons = new ArrayList();
   Image deleteThisButton = new Image(Resources.GetBitmap(Resources.BitmapResources.DeleteThisButton));
   Image deleteAllButton = new Image(Resources.GetBitmap(Resources.BitmapResources.DeleteAllButton));
   Image saveButton = new Image(Resources.GetBitmap(Resources.BitmapResources.SaveButton));
   Image cancelButton = new Image(Resources.GetBitmap(Resources.BitmapResources.CancelButton));

   bool buttonsVisible = false;

   void SetupDisplay()
   {
       mainWindow = display.WPFWindow;
       canvas = new Canvas();
       cameraImage = new Image(Resources.GetBitmap(Resources.BitmapResources.StartScreen));
       frames.Add(cameraImage.Bitmap);
       icon = new Image(Resources.GetBitmap(Resources.BitmapResources.CALIBRATE));
       frameNumber = new Text(Resources.GetFont(Resources.FontResources.SegoeUI_20), "");
       frameNumber.ForeColor = GT.Color.FromRGB(0, 200, 0);

       canvas.Children.Add(cameraImage);
       canvas.Children.Add(icon);
       canvas.Children.Add(frameNumber);

       canvas.Width = (int)display.Width;
       canvas.Height = (int)display.Height;

       Canvas.SetLeft(cameraImage, 0);
       Canvas.SetTop(cameraImage, 0);

       Canvas.SetRight(frameNumber, 5);
       Canvas.SetTop(frameNumber, 0);

       Canvas.SetLeft(icon, 5);
       Canvas.SetTop(icon, 10);

       // Add and position menu buttons
       canvas.Children.Add(deleteAllButton);
       canvas.Children.Add(deleteThisButton);
       canvas.Children.Add(cancelButton);
       canvas.Children.Add(saveButton);

       Canvas.SetLeft(deleteAllButton, 40);
       Canvas.SetTop(deleteAllButton, 5);
       Canvas.SetLeft(deleteThisButton, 180);
       Canvas.SetTop(deleteThisButton, 5);
       Canvas.SetLeft(saveButton, 40);
       Canvas.SetTop(saveButton, 125);
       Canvas.SetLeft(cancelButton, 180);
       Canvas.SetTop(cancelButton, 125);

       buttons.Add(deleteThisButton);
       buttons.Add(deleteAllButton);
       buttons.Add(saveButton);
       buttons.Add(cancelButton);

       foreach (Image button in buttons)
       {
           button.Visibility = Visibility.Hidden;
       }

       buttonsVisible = false;
       mainWindow.Child = canvas;
   }

The .Net Gadgeteer really has made building custom hardware devices and programs almost as simple as building just software only solutions. If you can code but have thought "hardware is hard" you really should check out the .Net Gadgeteer. It's likely easier than you think...

Here’s a few more links you might find interesting:

The Discussion

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to send us feedback you can Contact Us.