Monthly Archives: September 2018

Friday Product Post: No, I Am Your FPGA.

via SparkFun: Commerce Blog

Today we are excited to bring you the new Arduino MKR Vidor 4000, which combines the benefits of the SAMD21 and an FPGA. We also have the Raspberry Shake Home Earthquake Monitor, two Neutis boards to help fill the hole in your heart from the Edison’s passing, and a few other new products to fill your cart!

Vidor… Darth Vidor!

Arduino MKR Vidor 4000

Arduino MKR Vidor 4000

DEV-14870
$74.95

The Arduino MKR Vidor 4000 is highly configurable and powerful, and it can perform high-speed digital audio and video processing. With the Vidor, you can configure it the way you want to essentially create your own controller board. It comes loaded with hardware and potential: an 8 MB SRAM, a 2 MB QSPI Flash chip (1 MB allocated for user applications), a Micro HDMI connector, an MIPI camera connector, and Wifi and BLE powered by U-BLOX NINA W10 Series. It also includes the classic MKR interface, where all pins are driven both by SAMD21 and FPGA. Plus, it has a Mini PCI Express connector with up to 25 user programmable pins.


This shake brings an easy-to-use earthquake monitor to the yard!

Raspberry Shake - Home Earthquake Monitor (RS1D)

Raspberry Shake - Home Earthquake Monitor (RS1D)

SEN-14835
$214.99

The Raspberry Shake is a highly accurate seismograph you can use in your home, office and classroom. This Raspberry Pi accessory uses a single, vertical geophone as its sensor – a very sensitive yet rugged Earth motion microphone, widely used in the oil and gas industry to detect seismic vibration. The Raspberry Shake was originally designed with citizen scientists and educational facilities in mind, but can easily be used by other hobbyists, makers and enthusiasts!


Neutis Quad-Core Module

Neutis Quad-Core Module

DEV-14971
$59.95
Neutis Development Kit

Neutis Development Kit

DEV-14972
$239.95

Even though we made these available at the end of last week, we wanted to bring attention to these “Edison replacements” this Friday! The Neutis Quad-Core Module and Development Kit are loaded with features. Utilizing Neutis’ BSP based on Yocto, the system arrives with an up-to-date Linux kernel. The module is powered by a 64-bit ARM Cortex-A53 and a ARM Mali450 MPR GPU. It has 512 MB of RAM and 8 GB of eMMC storage. For connectivity, there are a plethora of wired and wireless options at your disposal. For wireless needs, the system rocks 802.11 b/g/n and Bluetooth 4.0 Dual-mode BLE, all with the built-in antenna. For your wired needs, the module’s two connectors give you access to an incredible peripheral set, including over 50 GPIO and a multitude of interfaces.


ESP-WROVER-KIT

ESP-WROVER-KIT

WRL-14917
$40.00

The ESP-WROVER-KIT is a development board produced by Espressif built around ESP32. This board is compatible with most ESP32 modules, including the ESP32-WROOM-32 and ESP32-WROVER (which you will find on the board itself). The ESP-WROVER-KIT features support for multiple amenities not typically found on other IoT devices, including a microSD card port, camera and LCD inputs, power mode selection and more. Each of the I/O pins have been broken out from the ESP32 module for easy extension, should you choose to use them.

We also have a few other new products to check out, so make sure to check out our New Products Page to see them all!


That’s it for this week, folks! As always, we can’t wait to see what you make! Shoot us a tweet @sparkfun, or let us know on Instagram or Facebook. We’d love to see what projects you’ve made!

We’ll be back next week with even more fantastic new products!

comments | comment feed

Enginursday: Creating Random Sequences with Rules

via SparkFun: Commerce Blog

When you put a bunch of electronics around trampolines in a room, and ask thousands of kids to jump on them, it’s only a matter of time before something fails. About three weeks after Boulder Bounces opened, we got an email telling us that it was failing on occasion.

alt text

Background of the project

We recently designed and installed an exhibit at the Museum of Boulder called Boulder Bounces. It’s a memory game much like the Simon Says Soldering Kit, but with trampolines. You can read more about it at this blog post, or watch the following video:

The original Simon Says uses the built-in random() Arduino function. While this works fine for the original game, Boulder Bounces needed some extra rules in the sequence generation to avoid “boring” bounce patterns. It’s not that fun to have many repetitions of the same trampoline, and any repetitions in the beginning of the sequence are not only difficult, but can lead to some serious confusion for the first-time player. Plus, when you’re playing with a group of jumpers (each standing on their own trampoline), it is loads more fun to ensure everyone gets to jump.

Let the investigation begin!

I have a lot of serial debug messages sending out from my Arduino Pro Mini on this project, so I was eager to plug in a FTDI basic and hear what was going on. My original email from the museum said that if they simply cycled power, it would start working again. Because of this, my first thought was that it was most likely failing in software, and not a hardware issue.

When I opened up the panel on the wall, it looked like the LEDs had been mistaken for buttons and pushed completely back into the panel. Those darn kids! I guess I can’t blame them; the gumdrop LEDs are big enough to be a button, but I needed to stay focused on the problem at hand.

Jumping right in

I played through an entire game once. It worked just fine. I played another round. No issue. Again, and again. Nothing. Then on the sixth game, right before I should have heard the winning sounds, it seemed to stall out.

I went to look at my serial debug, but it seemed to stop spitting out any serial debug at all. Hmmmm. When I am troubleshooting a code bug that involves a “stall out” like this, my first approach is to verify the point of failure and then work backward to find out the potential issue.

During my last game (right before the failure), I remember my serial debug was working properly. It was outputting each new sequence after each successful play correctly. But at my “win,” the serial debug stopped, so the failure must be occurring somewhere immediately after the last add_to_moves() was called.

A high-level look at the original code

Before we jump into any of the original code, I think it would be beneficial to share the high-level plan for gameplay, and my higher-level approach to creating the random sequence with rules.

The original gameplay code worked like this:

When you are playing a game, the Arduino will “play” back the sequence to you. At first, it only shows one trampoline light up, and you jump on it. Then the Arduino “randomly” chooses the next trampoline to add to the sequence. It plays back the entire sequence (which at this point is only two jumps long), and you must jump the sequence in order. Then it adds another, and so on. Once the sequence reaches eight and you successfully jump in the correct order, you win!

The specific part of the code that I’m talking about today is a function called “add_to_moves()”. This is a simple enough function in theory. Let’s take a look at the original function from the original Simon Says to start. Note, this code is from the button game, and was not used on the trampolines installation, but it’s a good place to start.

void add_to_moves(void)
{
  byte newButton = random(0, 4); //min (included), max (exluded)

  // We have to convert this number, 0 to 3, to CHOICEs
  if(newButton == 0) newButton = CHOICE_RED;
  else if(newButton == 1) newButton = CHOICE_GREEN;
  else if(newButton == 2) newButton = CHOICE_BLUE;
  else if(newButton == 3) newButton = CHOICE_YELLOW;

  gameBoard[gameRound++] = newButton; // Add this new button to the game array
}

First, you notice that the “random(0,4);” is generating the next “newButton” in the sequence. The following five lines of code are not really important in this discussion, but to quickly explain, we need to change them to the defined variables associated with each button choice available. For today, let’s just focus on the creation of newButton and then how it is added to the array, gameBoard[].

Looking at the original function add_to_moves(), it simply uses random() to add a new button to the sequence. This worked fine for the original Simon Says, but for Boulder Bounces, we needed to add in some rules to make it more interesting.

Add a while loop and some rules

My first approach to adding rules was to put it in a while loop. Inside this while loop, it would first grab a random newButton value from random(), then compare it against some rules. If it passes all the rules, then it would use it, and break out of the while loop. If it doesn’t pass a rule, then it would do nothing, stay in the while loop and try again.

alt text

The problem with this approach is that it is living on a prayer that random will eventually return something that will pass the rules. I knew this wasn’t perfect, but in all my development work on this project I never saw it get stuck. It usually tried a couple times at most, but eventually returned something that would work. It turns out that it can get stuck there, and something was causing it to stop trying.

For reference, the original code (with the actual rules - aka “if” statements) is as follows. You can see all of it here on my github commit. Specifically, here is my original add_to_moves():

void add_to_moves(void)
{
  while (1)
  {
    newButton = random(0, 3);
    if (!((newButton == gameBoard[gameRound - 1]))) // avoid repeats
    {
      // check to see if that button is already "maxed out"
      if ((newButton == 0) && (RED_seq_count == 2)); // do nothing
      else if ((newButton == 1) && (GREEN_seq_count == 3)); // do nothing
      else if ((newButton == 2) && (BLUE_seq_count == 3)); // do nothing
      //else if((newButton == 3) && (YELLOW_seq_count == 2)); // do nothing
      else break; // get out of this while loop and continue playing.
    }
  }

  // We have to convert this number, 0 to 3, to CHOICEs
  if (newButton == 0)
  {
    newButton = CHOICE_RED;
    RED_seq_count++;
  }
  else if (newButton == 1)
  {
    newButton = CHOICE_GREEN;
    GREEN_seq_count++;
  }
  else if (newButton == 2)
  {
    newButton = CHOICE_BLUE;
    BLUE_seq_count++;
  }
  else if (newButton == 3)
  {
    newButton = CHOICE_YELLOW;
    YELLOW_seq_count++;
  }

  gameBoard[gameRound++] = newButton; // Add this new button to the game array
}

You may also notice that my rules rely heavily on some new variables: RED_seq_count, BLUE_seq_count, etc. These are helping me keep track of how many times I’ve already included a specific color button in the sequence, so I can avoid favoring any button and ensure everyone gets to jump.

In an attempt to hone in on the problem, I added a little line of debug at the end of my add_to_moves() function.

if(debug) Serial.println("add_to_moves attempting...");

Now I would know whether it was trying at all, getting stuck in this while loop or stalling out elsewhere.

After much jumping and winning, I got another failure in the middle of a round. It stalled out, and my serial monitor looked like this:

alt text

Remember, my first failure was just before a “win.” Because this second failure was in the middle of a game, this was a new clue! This means that the failure is caused somewhere else in the code, and probably has nothing to do with the code just before a win.

Right before it stalled out, the entire serial monitor was filled with the message “add_to_moves attemping…” It was sending this message again and again as fast as my little Pro Mini could go. Something strange was going on. Why would it get stuck repeating this message, and then eventually give up?

The speed of the repetition of the debug message was also strange. When it seemed to be trying normally, the message would spit out to the terminal at a moderate pace. But when the failure would occur, the messages would speed up dramatically and eventually cause a stall out. After much finagling and many attempts to cause failures, I eventually gave up trying to find the root cause. I knew there was a better way, and so decided to start a different approach the the random generator with rules.

A better approach

alt text

To elliminate the possibility of any stall-outs, I introduced a new array called “on_deck_buttons[].” I would have my rules adjust this array, and then my random function can just choose from the good options. That way, random() will only be called once, and this removes the need to loop back around and try again and again.

I also beefed up my debug to get a better view into what was actually going on with all my variables and arrays.

Here is my new add_to_moves() function:

// Adds a new random button to the game sequence
void add_to_moves(void)
{
  byte newButton = random(0, 3); //min (included), max (exluded)
  int add_to_moves_counter = 0; // keep track of our while loop below for finding good new buttons, and see if this is jamming the game.
  if(gameRound == 0); // do nothing - newButton is randomly set above.
  else if((gameRound == 1) || (gameRound == 2)) // jumps 2 and 3 are important. for the first 3 jumps we want these to always hit each tramp once
  {
    while(1)
    {
      add_to_moves_counter++; // keep track of how many times we are trying to find a good new button to use (random might be stalling out here)
      int on_deck_buttons[2] = {0,0}; // these are used to help reandomize below
      newButton = random(0, 3); // pull in a first attempt at a nice new random button
      if((newButton == 0) && (RED_seq_count > 0))
      {
        on_deck_buttons[0] = 1;
        on_deck_buttons[1] = 2;
        newButton = on_deck_buttons[random(0, 2)]; // chooose randomly from on_deck_buttons - aka the only ones we want to choose from
        break;
      }
      else if((newButton == 1) && (GREEN_seq_count > 0))
      {
        on_deck_buttons[0] = 0;
        on_deck_buttons[1] = 2;
        newButton = on_deck_buttons[random(0, 2)]; // chooose randomly from on_deck_buttons - aka the only ones we want to choose from
        break;
      }
      else if((newButton == 2) && (BLUE_seq_count > 0))
      {
        on_deck_buttons[0] = 0;
        on_deck_buttons[1] = 1;
        newButton = on_deck_buttons[random(0, 2)]; // chooose randomly from on_deck_buttons - aka the only ones we want to choose from
        break;        
      }
      //else if((newButton == 3) && (YELLOW_seq_count == 2)); // do nothing
      //else break; // get out of this while loop and continue playing. This means that the new button is good to go. 
      else
      {
        Serial.println("error");
        break;
      }
      if(debug) Serial.println("add_to_moves attempting...");
      if(debug) Serial.print("gameBoard[gameRound-1]:");
      if(debug) Serial.println(gameBoard[gameRound-1]);
      if(debug) Serial.print("gameBoard[gameRound-2]:");
      if(debug) Serial.println(gameBoard[gameRound-2]);      
    }
    if(debug)
    {
      Serial.print("add_to_moves_counter: ");
      Serial.println(add_to_moves_counter);
      Serial.print("RED_seq_count: ");
      Serial.println(RED_seq_count);
      Serial.print("GREEN_seq_count: ");
      Serial.println(GREEN_seq_count);
      Serial.print("BLUE_seq_count: ");
      Serial.println(BLUE_seq_count);
    }
  }  
  else // only after you make it to step 3.
  {
      // attempt 1, works.
      // while((newButton == gameBoard[gameRound-1]) && (newButton == gameBoard[gameRound-2])) newButton = random(0, 4); // keep pulling in more variables until this isn't true.
      // basically, if it's the same as the previous 2 buttons, then it will keep finding a random number until it's "fresh".

      // attempt 2, attempting to add in limit per button to avoid leaving one jumper out.
    while(1)
    {
      add_to_moves_counter++; // keep track of how many times we are trying to find a good new button to use (random might be stalling out here)
      int on_deck_buttons[2] = {0,0}; // these are used to help reandomize below
      newButton = random(0, 3); // pull in a first attempt at a nice new random button

      // This ensures it's not going to repeat same button 3 times
      //if((convert_to_choice_byte(newButton) == gameBoard[gameRound-1]) && (convert_to_choice_byte(newButton) == gameBoard[gameRound-2])); // do nothing, try again 
      // check to see if that button is already "maxed out" (aka it has been used twice already)

      if((newButton == 0) && (RED_seq_count == 2))
      {
        on_deck_buttons[0] = 1;
        on_deck_buttons[1] = 2;
        newButton = on_deck_buttons[random(0, 2)]; // chooose randomly from on_deck_buttons - aka the only ones we want to choose from
        break;
      }
      else if((newButton == 1) && (GREEN_seq_count == 3))
      {
        on_deck_buttons[0] = 0;
        on_deck_buttons[1] = 2;
        newButton = on_deck_buttons[random(0, 2)]; // chooose randomly from on_deck_buttons - aka the only ones we want to choose from
        break;
      }
      else if((newButton == 2) && (BLUE_seq_count == 3))
      {
        on_deck_buttons[0] = 0;
        on_deck_buttons[1] = 1;
        newButton = on_deck_buttons[random(0, 2)]; // chooose randomly from on_deck_buttons - aka the only ones we want to choose from
        break;        
      }
      //else if((newButton == 3) && (YELLOW_seq_count == 2)); // do nothing
      //else break; // get out of this while loop and continue playing. This means that the new button is good to go. 
      else
      {
        Serial.println("error");
        break;
      }
      if(debug) Serial.println("add_to_moves attempting...");
      if(debug) Serial.print("gameBoard[gameRound-1]:");
      if(debug) Serial.println(gameBoard[gameRound-1]);
      if(debug) Serial.print("gameBoard[gameRound-2]:");
      if(debug) Serial.println(gameBoard[gameRound-2]);      
    }
    if(debug)
    {
      Serial.print("add_to_moves_counter: ");
      Serial.println(add_to_moves_counter);
      Serial.print("RED_seq_count: ");
      Serial.println(RED_seq_count);
      Serial.print("GREEN_seq_count: ");
      Serial.println(GREEN_seq_count);
      Serial.print("BLUE_seq_count: ");
      Serial.println(BLUE_seq_count);
    }
  }

  // We have to convert this number, 0 to 3, to CHOICEs
  if(newButton == 0) 
  {
    newButton = CHOICE_RED;
    RED_seq_count++;
  }
  else if(newButton == 1) 
  {
    newButton = CHOICE_GREEN;
    GREEN_seq_count++;
  }
  else if(newButton == 2) 
  {
    newButton = CHOICE_BLUE;
    BLUE_seq_count++;
  }
  else if(newButton == 3) 
  {
    newButton = CHOICE_YELLOW;
    YELLOW_seq_count++;
  }

  gameBoard[gameRound++] = newButton; // Add this new button to the game array
}

The trouble with failures that only happen once in a while is that it can require lots of data points and repeated testing to emulate the failure. For most software issues, this can sometimes be automated and done quickly, however, with exhibits like these that involve physical hardware, the true game play must be cycled again and again to create the failure.

The trampolines were failing randomly every 10-20 game plays, so that meant a lot of jumping. Never in my life have I had such a physically demanding code debug session! I did my fair share of jumping during the development of this project, but that paled in comparison to this debugging session.

If you have experienced any strange stall-out with the random() function, or have any other approaches to creating sequences like this, please share in the comments below. Also, please check out the github repo link below, and if you so feel inclined, we always love seeing any issues, forks, pull requests or comments. Thanks for reading and happy coding!

Boulder Bounces Github Repository

comments | comment feed

OSHWA Certification 2.0 is Here

via Open Source Hardware Association

Today at the Open Hardware Summit OSHWA launched version 2.0 of the open source hardware certification program. We have a new website, a new directory, and  lots of new resources for learning about open source hardware.  You should really check it out.

We announced our intention to create this new version of the certification back in March.  Since then we have been working in consultation with the board and the community to develop a new version of the site.  Version 2 of the certification site uses specific examples from the community to illustrate best practices and licensing decisions for creators of open source hardware.

Launched in 2016, the original certification program has been a success.  We have certified over 200 pieces of hardware from 27 countries on 5 continents.  The certification logo is making it easier to find open source hardware that meets the community definition of open source hardware and the certification process makes it easier to incorporate best practices into releasing open source hardware.

With that being said, there is always room for improvement.  In addition to the community, with the support of the Alfred P. Sloan Foundation we have been working with the Technology Law and Policy Clinic at NYU Law and the design team at Objectively think through the best way to make version 2 work for everyone.

Besides overhauling the look and feel of the site (embedding google docs in wordpress pages helped us get the program up and running quickly, but that approach admittedly comes with some design limitations), OSHWA had three primary goals for the the new website:

Consolidate Information

Since its founding, OSHWA has created a series of fantastic resources such as best practices and FAQs to help the community develop open hardware.  Each of these resources was developed in response to specific concerns, building up on existing resources and expanding explanations.

One side effect of that development history is that resources sometimes contained overlapping information that did not completely align.  It could also be hard to know exactly where to go to find a specific answer.

The new certification site borrows from the previously-developed resources and consolidates them into a unified presentation.  OSHWA has worked hard to create paths that are helpful for new members of the community just getting up to speed and existing members who want to take a deeper dive into something specific.  The new site allows you to skim along the top of information related to open source hardware and then immerse yourself in information when something catches your eye.

Licensing Guidance

There is no getting around the fact that licensing open source hardware is more complicated than licensing open source software. There are multiple elements to consider (hardware, software, documentation, etc.), multiple types of intellectual property at play, and some ambiguity around what is even protectable.

For the first time, OSHWA is providing specific guidance on licensing.  That guidance comes in two forms.

First, OSHWA recommends explicitly and individually licensing hardware, software, and documentation associated with a piece of certified hardware.  This will bring true clarity to future users.  The certification application now requires you to specify a license for each of these elements.

Second, OSHWA recommends specific licenses for each of those elements.  These recommendations are not exclusive, and OSHWA is happy to consider adding additional licenses as they are developed or as the community requests.  The recommended licences were chosen in an attempt to make it easy to pick a license that works for you.  This process is further simplified by providing examples of existing certified hardware that use a given license.  That means that users who are not sure which license to use can simply follow in the path of other hardware creators that they trust.

Searchability

The first version of the certification directory was a google spreadsheet embedded in a web page.  That made it easy to get certified hardware listed online.  It made it hard to actually explore the directory.

The new certification directory fundamentally redesigns the user experience. It is now easy to find hardware, search by features, and drill down into what is really available.  We hope that this makes the directory a much more useful resource for the community.

Next Steps

Version 2 is the newest version of the certification process, but it does not have to be the last.  Play around with it, certify something, and let us know what you think.  If you have ideas for features or information, or licenses you think we missed, please let us know in the forums.

SIK Project Ideas: Locker Alarm

via SparkFun: Commerce Blog

A few weeks ago I began to share some projects using parts from the SIK v4.0 to inspire users beyond the guide book. Today’s project was most certainly inspired by all of the cool back-to-schoool projects I wrote about last week – ladies and gentlemen, I introduce the Locker Alarm!

The locker alarm is a project using parts found in the SIK v4.0, so if you happen to have one at home, you are all set. The project includes a SparkFun Redboard, a breadboard, the SparkFun baseplate, the piezo speaker, a momentary pushbutton and photocell, a 330 ohm resistor, a 10k ohm resistor, and a AA battery pack and jumper wire.

locker alarm project

The diagram below illustrates the circuit. As you can see, the piezo speaker has two leads that are NOT polarized, meaning either can go to power or ground. In this circuit, one of the leads should go directly to ground, with the other connected to pin 6. Our next component, the button, also has two non-polarized leads. One lead will go directly to power and the second will go both to ground, via a 10k ohm resistor, and directly to pin 2. Finally we have the photocell. This guy has two non-poloraized leads as well. One will go to power, and the other to both ground, via a 330 ohm resistor, and directly to pin A0.

locker alarm circuit

Having a hard time seeing the circuit? Click on the wiring diagram for a closer look.



Now it s time to program our Arduino. The photocell is constantly checking the light level. If it is dark, then nothing should happen because the locker is closed. If the locker is opened, the photocell will register the light and trigger an alarm tone on the piezo speaker. The button will turn off the alarm, so it might be a good idea to hide the button somewhere discreet. Once the button is hit, the Arduino stops playing the alarm tone. The alarm will not be triggered again until the locker has been closed and reopened.

You can use the program below to get the alarm running, or you can challenge yourself to write it on your own! In any case, I have added some comments to my code to explain some of the logic!

//Locker Alarm by Melissa Felderman for SparkFun Electronics September 2018

int photoCell = A0; //declare photocell to pin A0
int photoVal; //declare variable to hold photocell value
int momBut  = 2; //declare momentary pushbutton to pin 2 (interrupt pin)
int butVal; //variable to hold the value of the momentary pushbutton
int piezo = 6; //declare piezo speaker to pin 6

//the below booleans are used for the alarm logic in the if statements in the loop. Both should be set to false at the top of the program
bool turnOnAlarm = false;
bool state = false;



void setup() {

  pinMode(6, OUTPUT); //let the arduino know that the piezo pin is an output
  pinMode(momBut, INPUT); //let the arduino know that the button is an input
  attachInterrupt(digitalPinToInterrupt(momBut), alarmOff, HIGH); //attach an interrupt to pin 2(the button) we do this so the button will register even during a delay

}

void loop() {

  photoVal = analogRead(photoCell); //read the photocell value and store it in the photoVal variable

  //the if statements below create the logic for the alarm. If the photocell reads a high light value and the state boolean is false, trigger the alarm
  //this will then change the booleans 'state' and 'turnOnAlarm' to true. While 'turnOnAlarm' is true, the alarm sound will play (funtion alarm();)
  //if the button is pressed(per the attach interupt in the setup), a function will be triggered 'alarmOff();' which turns the
  //boolean 'turnOnAlarm' back to false, so the alarm will stop playing. The alarm will not turn back on even though the photocell is
  //recieveing light because the boolean 'state' is still true. This boolean will remain true until the locker is closed and the
  //photocell is recieveing no light again, essentially resetting it for the next time.
  if (photoVal > 300 && state == false) {
    turnOnAlarm = true;
    state = true;
  } if (turnOnAlarm == true) {
    alarm();
  } if (turnOnAlarm == false) {
    noTone(piezo);

  }
  if (photoVal < 300) {
    state = false;

  }



}

//below is an alarm function this uses the tone fucntion to make the alarm sound on the piezeo. This function is called while 'turnOnAlarm' is true
void alarm() {

  for (int hz = 440; hz < 1000; hz += 25) {
    tone(piezo, hz, 50);
    delay(5);
    for (int i = 3; i <= 7; i++);

  }
  // Whoop down
  for (int hz = 1000; hz > 440; hz -= 25) {
    tone(piezo, hz, 50);
    delay(5);
    for (int i = 3; i <= 7; i++)
    {

    }
  }
}


//This function is triggered when the interrupt button is hit. If changes the value of 'turnOnAlarm' so that the user
//can stop the alarm while the locker is still open and the photocell is recieving light.
void alarmOff() {
  turnOnAlarm = !turnOnAlarm;

}


That’s all it takes to make your very own alarm locker. As is, you can stick this bad boy with the AA battery pack on the inside of your locker door with some 3M foam tape, and it’s ready to go. However, there is still plenty of room to take it a step further. If you have access to digital fabrication tools like a 3D printer or laser cutter, try to make an enclosure for your alarm. I made one on the 3D printer, hoping to amplify the sound of the piezo using an inverted cone shape.

locker alarm 3d printed enclosure

For even more advanced makers, try setting an alarm that wirelessly sends you a notification of the breach. Maybe you could turn it off remotely too! This project is not limited to students with lockers - it will work in any small enclosed space, like a desk drawer or closet. There is a ton of room to build, expand and improve upon this project! Tell us know your thoughts and ideas in the comments below!

comments | comment feed

IoT LED Dimmer

via Dangerous Prototypes

IOT-Dimmer

Sasa Karanovic shared a how-to on making a IoT LED dimmer:

Making a IoT LED dimmer that you can control via your PC, phone, tablet or any other device connected to the network is super simple, and I’m going to show you how.
I’m sharing my three channel LED dimmer that you can use to dim single RGB LED strip or dim three separate LED channels. I want to be able to control lights above my desk and also mix warm white and cool white strip to give me more flexibility over lighting while I’m working, taking pictures or watching movies.

See the full post on Sasa Karanovic’s blog.

#FreePCB via Twitter to 2 random RTs

via Dangerous Prototypes

BP

Every Tuesday we give away two coupons for the free PCB drawer via Twitter. This post was announced on Twitter, and in 24 hours we’ll send coupon codes to two random retweeters. Don’t forget there’s free PCBs three times a every week:

  • Hate Twitter and Facebook? Free PCB Sunday is the classic PCB giveaway. Catch it every Sunday, right here on the blog
  • Tweet-a-PCB Tuesday. Follow us and get boards in 144 characters or less
  • Facebook PCB Friday. Free PCBs will be your friend for the weekend

Some stuff:

  • Yes, we’ll mail it anywhere in the world!
  • Check out how we mail PCBs worldwide video.
  • We’ll contact you via Twitter with a coupon code for the PCB drawer.
  • Limit one PCB per address per month please.
  • Like everything else on this site, PCBs are offered without warranty.

We try to stagger free PCB posts so every time zone has a chance to participate, but the best way to see it first is to subscribe to the RSS feed, follow us on Twitter, or like us on Facebook.