Skip to content

Wireling Kickstarter Basic Kit Tutorial

Gif demonstrating the behavior of the Wirelings with the program included in the tutorial running.

If you backed the Wireling Kickstarter for the Basic Kit, and selected a WirelingZero, there is ALREADY code loaded onto the Tiny processor (Before 12-15-19, WirelingZero basic kits were shipped out with a simple blink program that blinks a green onboard LED, and not the program discussed on this page). To see what it does, follow this scheme for plugging in the Wirelings:

Update: The code for this kit was updated on 01-20-2020 due to a software issue related to the Buzzer Wireling. This issue has been resolved and the updated code is used in the tutorial below.

Wireling Port Assignments
Port 0
Port 1
Port 2
Port 3

Plug in the rechargeable battery to the battery port. (You may need to charge the battery, to do so just plug it into the WirelingZero and plug the unit into a power source with a MicroUSB cable)

The screen on Port 0 will display the Lux readings from the Ambient Light Sensor on Port 1, and also display the HIGH or LOW state of either the Digital Sensor or Large button on Port 2. Trigger these by putting a magnet close to the hall sensor, or by pressing the button. Once the Wireling on Port 2 is triggered, the RGB LED Wireling will light up, or the Buzzer will play a sequence of notes.


If you did not select the WirelingZero, or you were not a backer, the rest of this page is a tutorial for uploading the same program to any Wireling platform!

This tutorial shows you how to use ALL SIX of the Wirelings included in the Wireling Kickstarter Basic Kit in one program! Before proceeding, it is recommended that you have already gone through at least the setup tutorial of the WirelingZero or Wireling Arduino Shield to ensure you have any software this program depends on:


Materials

In order to interface with any Arduino-based board, you'll need the Arduino IDE.

There are multiple processor/adapter combinations that can be used with Wirelings. Use the following table to find the combination that works for you.

Processor Adapter Programming Cable
+
-
-
Arduino USB A to B Cable
Raspberry Pi

In order to interface with Wirelings, you'll need the appropriate number of Wireling Cables and the Wireling.h Library (You can download this from GitHub as linked, or from the Library Manager in the Arduino IDE).

The table below details which Wirelings are used on each port. The tutorials and libraries for each of these Wirelings are also included.

Wireling Learn Library
Port 0
Port 1
Port 2
Port 3

Hardware Assembly

Depending on the development system you choose, you will need to put together a TinyDuino stack using the 32-pin tan connectors, or you will just need to plug in your Wirelings to the following Ports:

Wireling Port Assignments
Port 0
Port 1
Port 2
Port 3

If you want to change which ports these are, there is a section above the setup() loop in the program that contains the port and pin definitions, you can change these values to suit your needs.


Software setup

The only external libraries you will need are the FastLED library, and the Wireling library. If you have not already, download the libraries found under the Software section above. If you have never installed an Arduino library, check out our Library Installation Help Page for some quick how-to information.

Then, make the correct Tools selections for your development board. If you are unsure what to select, you can double check the Help page that mentions the Tools selections needed for any TinyCircuits processor.


Upload Program

Upload the program to your development board of choice!

Wireling Program
/************************************************************************
   Wireling Basic Kit Shipment Program
   This program uses all six of the Wirelings included with the Basic Kit:
   Port 0: 0.42" OLED Screen Wireling
   Port 1: Ambient Light Sensor Wireling
   Port 2: Digital Sensor Wireling OR Large Button Wireling
   Port 3: RGB LED Wireling OR Buzzer Wireling
   When plugged in according to the above mapping, the 0.42" Screen will
   display the lux value read from the light sensor, and will also display
   the HIGH or LOW state of whatever Wireling is connected to Port 2 (The
   digital hall, or large button). When the Wireling on Port 2 reads LOW,
   the RGB LED or Buzzer connected to Port 3 will either light up a short
   RGB sequence, or play a few notes, respectively.
   Hardware by: TinyCircuits
   Written by: Laveréna Wienclaw for TinyCircuits
   Initiated: 11/2/2019
   Updated: 01/20/2020
 ************************************************************************/

#include <Wire.h>                   // For I2C communication
#include <Wireling.h>               // For interfacing with Wirelings
#include <TinierScreen.h>   // For interfacing with the 0.42" OLED
#include <GraphicsBuffer.h> // For building a screen buffer for the 0.42" OLED
//#include "exampleSprites.h"         // Holds arrays of example Sprites
#include "pitches.h"                // Tones used with the Buzzer
#include <FastLED.h>                // For the RGB LED

// Make compatible with all TinyCircuits processors
#if defined(ARDUINO_ARCH_AVR)
#define SerialMonitorInterface Serial
#elif defined(ARDUINO_ARCH_SAMD)
#define SerialMonitorInterface SerialUSB
#endif

/***************************** 042 Screen OLED Varibles ****************************/
#define OLED_042_PORT 0 // use Port 0 for screen
#define OLED_042_RESET (int) A0 // use Port 0 reset pin
#define OLED_042_WIDTH 72
#define OLED_042_HEIGHT 40
TinierScreen display042 = TinierScreen(TinierScreen042);
GraphicsBuffer screenBuffer042 = GraphicsBuffer(OLED_042_WIDTH, OLED_042_HEIGHT, colorDepth1BPP);

/************************* Ambient Light Sensor Variables **************************/
// Communication address with the sensor
#define TSL2572_I2CADDR     0x39

// Sets the gain
#define   GAIN_1X 0
#define   GAIN_8X 1
#define  GAIN_16X 2
#define GAIN_120X 3

//only use this with 1x and 8x gain settings
#define GAIN_DIVIDE_6 true

// Global variable for gain value used to Read the sensor
int gain_val = 0;

/***************************** Buzzer Sensor Variables *****************************/
// notes in the melody:
int melody[] = {
  NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 1, NOTE_B3, NOTE_C4
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  4, 8, 8, 4, 4, 4, 4, 4
};

/******************************** RGB LED Variables ********************************/
#define NUM_LEDS 1 // This is the number of RGB LEDs connected to the pin
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
int brightness = 128; // Brightness is on a scale of 0-255, 128 is 50% brightness

/*********************************** Wireling Variables ****************************/
#define AMBIENT_PORT 1
#define BUTTON_HALL_PIN A2
#define BUZZER_RGB_PIN A3

bool highOrLow = false;

void setup() {
  SerialUSB.begin(9600);
  Wire.begin();
  Wireling.begin(); // Enable & Power Wirelings

  /* * * * * * * * * 0.42" Screen Stuff * * * * * * * */
  Wireling.selectPort(OLED_042_PORT);
  display042.begin(OLED_042_RESET);
  if (screenBuffer042.begin()) {
    //memory allocation error- buffer too big!
  }
  screenBuffer042.setFont(thinPixel7_10ptFontInfo);

  // Initialize Ambient Light Sensor
  Wireling.selectPort(AMBIENT_PORT);
  TSL2572Init(GAIN_16X);

  // Initialize RGB LED
  FastLED.addLeds<WS2812, BUZZER_RGB_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(brightness);
  pinMode(BUZZER_RGB_PIN, OUTPUT);
}

void loop() {
  String digStr;
  char digBuf[13]; // buffer for digital input character array

  /************************************ Port 1 ************************************/
  Wireling.selectPort(AMBIENT_PORT);
  float Lux = Tsl2572ReadAmbientLight();

  // Create a char array with results to print to screen
  String luxStrVal = String(Lux);
  String luxFullString = ("Lux:" + luxStrVal);
  char luxBuf[10];
  luxFullString.toCharArray(luxBuf, 10);

  /************************************ Port 2 ************************************/
  highOrLow = digitalRead(BUTTON_HALL_PIN);
  if (highOrLow) {
    digStr = "Port 2: HIGH";
  } else if (!highOrLow) { // button was pressed, or hall was activated
    digStr = "Port 2: LOW";
  } else {
    digStr = "Port 2: N/A";
  }
  digStr.toCharArray(digBuf, 13);

  /************************************ Port 0 ************************************/
  Wireling.selectPort(OLED_042_PORT);
  screenBuffer042.clear();
  screenBuffer042.setCursor(0, 0);
  screenBuffer042.print(digBuf);
  screenBuffer042.setCursor(0, 24);
  screenBuffer042.print(luxBuf);
  Wire.setClock(1000000);
  display042.writeBuffer(screenBuffer042.getBuffer(), screenBuffer042.getBufferSize()); // write buffer to the screen
  Wire.setClock(50000);

  if(!highOrLow) {
    lightRGB();
    playBuzzer();
  }
}

/************************************* Ambient Light Functions **********************************/
// Used to interface with the sensor by writing to its registers directly
void Tsl2572RegisterWrite(byte regAddr, byte regData) {
  Wire.beginTransmission(TSL2572_I2CADDR);
  Wire.write(0x80 | regAddr);
  Wire.write(regData);
  Wire.endTransmission();
}

// Initializes the light sensor to be ready for output
void TSL2572Init(uint8_t gain) {
  Tsl2572RegisterWrite( 0x0F, gain );//set gain
  Tsl2572RegisterWrite( 0x01, 0xED );//51.87 ms
  Tsl2572RegisterWrite( 0x00, 0x03 );//turn on
  if (GAIN_DIVIDE_6)
    Tsl2572RegisterWrite( 0x0D, 0x04 );//scale gain by 0.16
  if (gain == GAIN_1X)gain_val = 1;
  else if (gain == GAIN_8X)gain_val = 8;
  else if (gain == GAIN_16X)gain_val = 16;
  else if (gain == GAIN_120X)gain_val = 120;
}

// Read the lux value from the light sensor so we can print it out
float Tsl2572ReadAmbientLight() {
  uint8_t data[4];
  int c0, c1;
  float lux1, lux2, cpl;

  Wire.beginTransmission(TSL2572_I2CADDR);
  Wire.write(0xA0 | 0x14);
  Wire.endTransmission();
  Wire.requestFrom(TSL2572_I2CADDR, 4);
  for (uint8_t i = 0; i < 4; i++)
    data[i] = Wire.read();

  c0 = data[1] << 8 | data[0];
  c1 = data[3] << 8 | data[2];

  //see TSL2572 datasheet: https://www.mouser.com/ds/2/588/TSL2672_Datasheet_EN_v1-255424.pdf
  cpl = 51.87 * (float)gain_val / 60.0;
  if (GAIN_DIVIDE_6) cpl /= 6.0;
  lux1 = ((float)c0 - (1.87 * (float)c1)) / cpl;
  lux2 = ((0.63 * (float)c0) - (float)c1) / cpl;
  cpl = max(lux1, lux2);
  return max(cpl, 0.0);
}

void lightRGB() {
  for (int x = 0; x < NUM_LEDS; x++) { // cycle through all LEDs attached to LED_PIN
    leds[x] = CRGB( 255, 0, 0); // RED
    FastLED.show();
    delay(100);
    leds[x] = CRGB(0, 255, 0); // GREEN
    FastLED.show();
    delay(100);
    leds[x] = CRGB(0, 0, 255); // BLUE
    FastLED.show();
    delay(100);
    leds[x] = CRGB(0, 0, 0); // NOTHING
    FastLED.show();
    delay(5);
  }
}

void playBuzzer() {
  for (int thisNote = 0; thisNote < 8; thisNote++) {
    // to calculate the note duration, take one second divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(BUZZER_RGB_PIN, melody[thisNote], noteDuration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);

    noTone(BUZZER_RGB_PIN); // stop the tone playing
  }
}

You may notice in the Wireling Variables section above the setup() loop that there are a mix of PORT and PIN definitions. The majority of Wirelings use port definitions because they use I²C to communicate with the processor, other Wirelings just need an Input/Output pin. These differences are something to keep in mind as the 0.42" Screen, and Ambient Light Sensor are I²C devices, while the rest of the Wirelings just use Input/Output pins A0-A3.

Note: If nothing is plugged into Port 2, Port 2 will have a consistent LOW reading, making the Wireling on Port 3 continuously trigger


Contact Us

If you have any questions or feedback, feel free to email us at info@tinycircuits.com or make a post on the forum.

Show us what you make by tagging @TinyCircuits on Instagram, Twitter, or Facebook so we can feature it!

Thanks for making with us!