Recent Posts

Pages: [1] 2 3 ... 10
Digispark (Original) Support / Re: Button input not working
« Last post by KASA on Today at 04:31:16 am »
Did you connect the blue wire to pin 5 on the Digispark?
Digispark (Original) Support / Re: Error code
« Last post by KASA on Today at 04:27:13 am »
Try removing the const in front of the char
Digispark Projects / Re: Genie Garage Door opener using Digispark Pro
« Last post by DaveFromRI on August 16, 2017, 05:28:07 am »
Version 2 of this project, even though I doubt anyone cares. But, perhaps in the future someone will find this thread and appreciate my admittedly limited effort.

Here is "Version 2", mostly program fixes where I didn't like the way I programmed it initially (as compared to true bug fixes). The code is well commented, so I'll only post the changes here:
- When auto-closing, any key-press on the outside keypad will reverse the door and open it (a safety feature).
- While beeping (warning) about auto-close, any key will stop the beeping (and subsequent timeout/closing). This
   will allow one to enter "OPEN" (or any valid code).
- The auto-close time is reduced from 5 minutes to 3. After using it a bit of time, 3 minutes is sufficient for me (with
   an increase from 20 seconds to 30 seconds warning beeping).
Code: [Select]
 * Garage_Door_Too, a Garage Door Opener specifically to utilize the 'Genie" keypad but add to it's functionality.
 * by DaveFromRI, first release: August, 2017.
 * VERSION 2 - Safety feature added: During auto-close any key pressed will reverse the door back up.
 *             Additionally, any keypress during the auto-close warning will reset the door-open timer.
 * --------------------------------------------------------------
 * =    Licensed under the CC-GNU GPL version 2.0 or later      =
 * =          =
 * --------------------------------------------------------------
 * The name "Garage Door Too" came from the fact that I found at least one other project similar to mine, and
 * I wanted to differentiate between the two. Our projects are different, but complimentary, which is good.
 * 1) This project is intended to be used with the DigiStump "Digispark Pro" product:
 *    (
 *    Granted several years old, but a friend of mine had bought two way back, couldn't figure them out, and asked me
 *    if I could help (so I did).
 * 2) Besides a standard Micro-USB charger for power, this design requires several accessory components:
 *    a) A relay board with an embedded on-board driver transistor (or equivalent).
 *    b) A piezo electric element (the 'element' only, no driver circuitry...the Digispark Pro can do the job).
 *       (
 *    c) A wired door sensor switch to be attached to the garage door. Similar to used in security alarm systems,
 *       it should be a "Normally Closed" magnetic contact. My code can easily be changed for a 'Normally Open' if necessary.
 *       (
 *    d) A 14-pin IC socket
 *       (
 * 3) I never got around to taking a picture of the PCB, but here's the Digispark Pro wiring (see attached picture for reference):
 *    a) Yellow digital pins 6-12 are for keypad in (a 3x4 matrix). Because the keypad comes with a ribbon cable with
 *       protruding wires, I simply took an old IC socket, cut off one side, and soldered it directly to the Digispark Pro.
 *       If you're not sure which way to plug in the notched keypad cable, please see the notes in the code.
 *    b) Shared with the on-board LED, the external relay board is tied to yellow digital pin 1. This was not an oversight;
 *       I wanted to be able to test if the on-board LED would turn on as programmed, without needing a relay.
 *    c) The Piezo element positive lead is connected to the yellow Digispark Pro digital pin 0, and negative to ground.
 *       In the interest of full disclosure, I didn't buy the one in the link, but ripped it out of a broken blood-pressure machine.
 *    d) Lastly, the door switch is connected to the yellow Digispark Pro digital pin 2. REMINDER: This switch contact &
 *       magnet must be mounted to the garage door and frame so that when the door is closed, they match together.
 *       Like the piezo, the other wire of this switch contact goes to the Digispark Pro ground.
 * 1) Easy programming: There is no need to remove some hard-to-get-off cover and locate a dark & hard to find switch,
 *    just punch in "PROG" and then your new 4-digit code. Done! Forgot your code? Open the door with a key and program it!
 * 2) My code is currently set to close the door automatically after 3 minutes (with a 30 second warning). But what if you're
 *    working in the garage and need the door to stay open? Easy! Just press "OPEN", and it won't close on you!
 *    Yes, the 3 minute auto-close is because more than once I forgot to close the door and drove away. Also, either
 *    entering the correct code *or* closing the door resets this feature.
 * 3) If the garage door fails to close at the 3 minute mark (due to an obstruction), it will try again in 3 minutes.
 * 4) Both of the two above reserved PIN codes (7837 & 8874) will only work when the door is open, and are disallowed
 *    when programming your own PIN code (you'll hear a nasty beep).
 * 5) After 3 failed attempts to enter an open code, the unit will start beeping (to alert you that someone has been
 *    tampering). Either entering the correct code or opening the door (with a key?) will shut off the annoying beeping.
 * When someone enters the wrong code too many times, it was a tough decision on how to handle it. Most people prefer
 * to lock out the "hacker" for a minute or so, but honestly, in my MANY years of having a garage, it has never happened.
 * But to *not* code for it would be foolish, so I opted for the "Beep Constantly" option, specifically so that if an
 * authorized person accidentally hits the wrong code, the correct code they can quickly silence the warning and open the door.
 * A lot more thought went into this project than one might expect. For example, some code I've seen allows multiple
 * access codes, but in my lifetime (quite long), the only time I've had to 'share' access with my garage was someone
 * whom I absolute trust. So why bother? For the same reason, I abandoned the thought of a "One-Time-Open" code.
 * Another feature I opted against (like both the original Genie device & another project I found), a user cannot press
 * any key (within so many seconds) on the keypad to act as a "Close now" button. IMO, I see two problems with this:
 * 1) The keypad DOES wear (I've already had to replace it twice). Either install a doorbell button on the inside or
 *    force the user to type in the 4-digit pin. These keypads are too expensive to waste on frivolous presses.
 * 2) Very intentionally, I use the "Door open" state to allow for reprogramming or telling the logic to stay open.
 *    I think this concept is more user friendly, as most people have doorbell buttons plus wireless remotes in their car.
 * As much as reasonable, I added lots of comments to help people, so...well...I hope they do.
 * Thanks for looking at my very first public release of Arduino code.

// Kind of annoying how you get this non-fatal warning when compiling. Just ignore it:
// WARNING: Category '' in library EEPROM is not valid. Setting to 'Uncategorized'
#include <EEPROM.h>
#include <Keypad.h>
#include <DebouncedSwitch.h>
#include <elapsedMillis.h>

#define PIEZO_PIN 0         // Piezo electric element (no driver circuity needed).
#define RELAY_PIN 1         // The relay output pin, shared with the LED for testing purposes.
#define INPUT_PIN 2         // The normally-closed magnetic door switch (closed when door is closed).
#define PIEZO_FREQ 2000     // A value to adjust to match the frequency of the piezo device.
                            // NOTE: I had to tweak the frequency for maximum volume. Your piezo may tweaking.
#define RELAY_DELAY 500     // Number of milliseconds to hold relay energized.
#define KEY_TIMEOUT 10000   // Number of milliseconds before keys are erased.
#define ROWS 4              // Keypad has four rows.
#define COLS 3              // Keypad has three columns.
#define RELAY_ON HIGH       // A tad unnecessary, but incase a given relay board operates on opposite logic.
#define RELAY_OFF LOW       //    "           "           "           "           "           "
#define CLOSE_SOON 150000   // The timer value to warn that the door is about to close (4 minutes, 30 seconds).
#define CLOSE_NOW 180000    // The timer value when to close the door (3 minutes here).
#define OPEN_CODE "7837"    // Reserved code for locking the door open (spells out "OPEN").
#define PROG_CODE "8874"    // Reserved code for programming a new code (spells out "PROG").
#define DEFAULT_PIN "1234"  // Upon first running of the code, the EEPROM is programmed with this 4-digit string.
#define FAILED_ATTEMPTS 3   // How many times a person can enter the wrong code before it starts beeping like crazy.
#define E_TEST_CODE 245     // The hex code of A5 (binary 10100101) to see if the EEPROM is already programmed.
                            // Admittedly a pretty lazy 'check', but A5 is not an ASCII character and it's binary
                            // pattern is relatively unlikely to come up at exactly EEPROM address 5.

// Define the Keymap
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', 'z'}
// This definition is for when the GENIE keypad is plugged in notch down (away from USB).
byte rowPins[ROWS] = { 7, 8, 11, 12};
byte colPins[COLS] = { 6, 9, 10};

// This definition is for when the GENIE keypad is plugged in knotch up (towards USB).
byte rowPins[ROWS] = { 11, 10, 7, 6};
byte colPins[COLS] = { 12, 9, 8};

// Create the keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

// Set up to debounce the magnetic door sensor
DebouncedSwitch doorSensor(INPUT_PIN);

// Set up two timers for they keypad and door
elapsedMillis keyTimer;
elapsedMillis doorTimer;

// Define some global variables and set them to an intial state
byte badCounter = 0;      // Counter for the number of times a bad pin has been entered
bool progMode = false;    // Indicator that we've entered program mode
bool doorDown = false;    // A mirror of the actual door state, used to detect new state if needed
bool openMode = false;    // Indicatator that "Open Mode" is active
bool autoClose = false;   // Indicatator that we've started the auto-close process
String pinCode =  "";     // Variable to hold Pin Code (4 digits)

// As the routine is self-described, set up the keyboard, our timers, pin configuration, & door state.
void setup() {
  keyTimer = 0;
  doorTimer = 0;
  digitalWrite(RELAY_PIN, RELAY_OFF);
  if (doorSensor.isDown()) doorDown = true;

// The main program loop to check the keypad, door status, and timer events
void loop() {
  char key = kpd.getKey();

  // Check for a valid key.
  if (key) {
    keyTimer = 0;

    // New logic feature in version 2. If door is beeping for auto-close, any key stops it and
    // will reset the door timer, but valid codes (like OPEN & PROG) still work.
    if (doorTimer > CLOSE_SOON and !openMode and !doorDown and !autoClose) doorTimer = 0;

    // New safety feature in version 2. If the door is auto-closing and any key is pressed
    // on the keypad, stop the door and then reverse it back up.
    if (autoClose) {
      key = '*';    //Fill this with the clear key just to satisfy the remaining tests
    // Use the star key as a "Clear" function, to mimize mistaken entries.
    if (key == '*') {
      // Clear pinCode and program mode
      pinCode = ""; 
      progMode = false;

    // Some other key pressed besides "*", so process it
    else {
      // Accumulate entered keys until we have 4. The "if" is probably not necessary because
      // one can't press keys faster than this loop, but in the event the code is modified in
      // some way (like keybounces become a problem), it's a nice, short, safeguard.
      if (pinCode.length() < 4) pinCode += key;

      // Four digits entered, so let's figure out what the user entered.
      if (pinCode.length() == 4) {
        // If the "program" code was entered and the door is not down, enter program mode.
        if (progMode and !doorDown) {
          // First make sure the user isn't trying to use one of the two reserved codes.
          if (pinCode == OPEN_CODE or pinCode == PROG_CODE) {
            // Invalid pin code so make a nasty beep.
            for (int i = 0; i < 80; i++) playBeep(1, 5);
          else {
            // We are in program mode and a valid set of 4 digits were entered, so let's save them.
            // Beep four short beeps to let the user know they were successful.
            playBeep(4, 100);
          progMode = false;
        // If the door is open and the user entered the program code, enter reprogram mode
        else if (pinCode == PROG_CODE and !doorDown and !progMode) {
          // Beep two short beeps to let the user know that they've entered program mode.
          playBeep(2, 100);
          progMode = true;
        // Check to see if the user has set open mode (the door stays open with no timer)
        else if (pinCode == OPEN_CODE and !doorDown and !progMode) {
          // Beep two long beeps to let the user know they've entered door open mode.
          openMode = true;
          playBeep(2, 500);
        // If the correct pin was entered, open or close the door.
        else if (readPin("") == pinCode and !progMode) {
          badCounter = 0;
        else {
          // The only way we could get here is if an invalid code was entered, so let's count
          // how often this happens.
        pinCode = "";  // Clear pinCode for next set of 4 characters
  else {
    // If no key is pressed after too long, clear all stored keys. Also cancel program mode if timeout.
    if ((pinCode != "" or progMode) and keyTimer > KEY_TIMEOUT) {
      pinCode = "";
      progMode = false;
  // If the door is about to close, start beeping.
  if (!openMode and doorTimer > CLOSE_SOON and !doorDown) playBeep(1, 30);

  // If the door is open for more than the set limit, shut it. Reset the timer so that in the event it
  // doesn't close (like it hits an object), it can try yet after the same duration until successful.
  if (!openMode and doorTimer > CLOSE_NOW and !doorDown) {
    doorTimer = 0;
    autoClose = true;

  // If the door is closed and the wrong code is entered 3 times, start beeping until the door opens
  // or the correct code is entered. We could lock out the keypad for some duration, but honestly,
  // there is little evidence of people "playing" with garage door keypads trying to guess codes.
  // Besides, this code alerts the owner (by beeping) that someone has made a failed attempt.
  if (doorDown and badCounter >= FAILED_ATTEMPTS) playBeep(1, 50);

  // Debounce the door sense switch and set the state of our boolean variable, doorDown to reflect
  // the current door position.
  if (doorSensor.isDown() != doorDown) {
    // The door changed state, so let's store the new state and clear out some important variables
    doorDown = doorSensor.isDown();

    // If one needs to detect *which* transition the door has made, this code can detect it.
    if (doorDown) {
    // Door just closed
    else {
    // Door just opened

// Play a beep sound, sending the number of beeps and the duration (in milliseconds)
void playBeep(int repeat, int duration) {
  for (int i = 0; i < repeat; i++) {
    tone(PIEZO_PIN, PIEZO_FREQ, duration);
    delay(duration * 1.30);

void clearVars() {
  pinCode = "";
  progMode = false;
  openMode = false;
  autoClose = false;
  doorTimer = 0;
  badCounter = 0;
// Trigger the relay for the desired amount of time
void triggerRelay() {
  digitalWrite(RELAY_PIN, RELAY_ON);
  digitalWrite(RELAY_PIN, RELAY_OFF);

// Read the pin code, set a pin code, or if a new device, create a 'Default' pin code "1234". It's pretty
// redundant to check EVERY TIME if the memory is programmed properly, but two functions combined into one
// seems to make more sense. After all, it's just a simple (non-destructive) eeprom read, so why care?
String readPin(String newCode) {
  // initialize string variables
  char pinChar; //Used to read individual characters from EEPROM
  String storedCode; // Used to hold the memorized code

  // Use E_TEST_CODE to signal memory already programmed
  if ( == E_TEST_CODE) {
    // This is a lazy way of detecting whether to program a new code or not. If something was
    // passed to this routine and NOT 4 digits, then just return the stored 4-digit code.
    if (newCode.length() != 4) {
      for (int i = 0; i < 4; i++) {
        pinChar =;
        storedCode += pinChar;
    // The only way to get here is if 4 digits were passed, so let's program them into the eeprom.
    else {
      for (int i = 0; i < 4; i++) {
        // Very intentionally we use 'put', as it's less destructive by checking the contents first.
        EEPROM.put(i, newCode.charAt(i));
      storedCode = newCode;
  else {
    // The only way to get here is if our EEPROM test code is not already in address 4 of the
    // eeprom, so let's store it now plus the default..
    EEPROM.put(4, E_TEST_CODE);
    storedCode = DEFAULT_PIN;
    for (int i = 0; i < 4; i++) {
      EEPROM.put(i, storedCode.charAt(i));
  // Whether we read the eeprom or set the default, return the value.
  return storedCode;
Oak Support / Re: "Oak by Digistump" disabled in Arduino IDE Boards list
« Last post by PeterF on August 14, 2017, 05:33:30 am »
It's not disabled, that is the (group of boards) heading for that section of the list. Same as the Arduino AVR Boards one at the top of the list. You've picked the correct option, the first of the three in that list. Be warned though, if you have flakey internet or wifi, that option *will* result in your Oak rebooting into config mode where it will wait for you to tell it what access point to connect to. You may want to consider the manual config mode option, where it only goes into config mode if the code crashes and it can reboot it's way out, or if you connect P1 to GND.
Digispark (Original) Support / Issue about driver
« Last post by ufaforwork2 on August 14, 2017, 03:31:32 am »
I get this message when I try to upload on my digispark :

Code: [Select]
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
> Please plug in the device ทางเข้าufabet
> Press CTRL+C to terminate the program.

I'm running v1.6.5 IDE on windows 10
My arduino nano works perfectly. สมัครufabet
General Electronics / WS2811 Led strips
« Last post by on August 13, 2017, 11:41:20 pm »
Hi all
I have built a light box that uses 45 strips at 60 pixels per meter.  2106 Pixels in total.  Due to the length i need to add extra power to the strips along the box.  Because the strips use the negative as a return for the signal finding communication issues as soon as I add a extra negative.  Anyone know how to add without this problem happening.
I wanted to say thanks for this info. I  had claimed some oaks a while ago (successfully) on the particle cloud, but couldn't use any libraries. This info let me swap to generic ESP8266, which was awesome!

I also wanted to add a note about the OTA updating - I couldn't see my port, and it turned out that I had to enable IPv6 in my router to be able to see the mDNS sent out by the oak. Before I did that, I couldn't see it even with Bonjour Browser, and afterwards I can and it works to upload code - haven't tried adding additional code with the OTA sketch, but baby steps.

I was also able to upload binaries with the Example > ESP8266WebServer > WebUpdate example, even without mDNS working, if I went to [oak IP]/update and used exported bins, so that would have worked if I couldn't have updated router settings.

Just to avoid having to power on/off the oak when uploading new code, but eh, it's less confusing. I still have my serial port connected for debugging, but I don't need to futz with P2 low/high.
Oak Support / "Oak by Digistump" disabled in Arduino IDE Boards list
« Last post by atkulp on August 11, 2017, 12:09:00 pm »
Like the title says...

The help page ( says
"With the install complete, close the “Boards Manager” window and select the Oak by Digistump from the Tools→Boards menu."

This menu option is disabled though.  I can deploy using the "Oak by Digistump (Pin 1 Safe Mode - Default) option, but what's the deal?

Digispark Pro Support / digispark pro as USB keyboard
« Last post by yo2ldk on August 11, 2017, 11:19:10 am »

 I need to setup the Pro as keyboard,
with the following code, digispark simple work well, but with pro, it says USB not recognized, where is the mistake?
both are compiling without errors:

Code: [Select]
#include "DigiKeyboard.h"

uint8_t button1 = 0;
uint8_t button2 = 2;
uint8_t value1 = LOW;
uint8_t value2 = LOW;

void setup() {
 pinMode(button1, INPUT);
 pinMode(button2, INPUT);

void loop() {
  value1 = digitalRead(button1);
  value2 = digitalRead(button2);

  if(value1 == HIGH) {

  if (value2 == HIGH) {
Digispark (Original) Support / Error code
« Last post by Hero on August 10, 2017, 06:30:15 am »

I am new to all these things but i got this error code and don't know how to fix it.

Arduino: 1.8.3 (Windows 10), Board: "Digispark (Default - 16.5mhz)"

Build options changed, rebuilding all
In file included from C:\Users\minec\Documents\Arduino\Loot\Loot.ino:1:0:

sketch\digiKeyboard.h:61:1: error: too many initializers for 'const char [22]'



exit status 1
Error compiling for board Digispark (Default - 16.5mhz).

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

If anyone knows what this mean/how to fix it please let me know Thank you


Pages: [1] 2 3 ... 10