Thursday, December 31, 2015

Building an AC Power Switch Development Board

Ever want to create a design that automates turning on or off an AC powered device such as a light or a heating system? Well this video is for you! In this video we look at how to create a development board for switching on and off AC power. The switch is implemented with a TRIAC which is a semiconductor device so no moving parts like a relay based design. You can access the Eagle PCB layout files from this link https://github.com/ForceTronics/AC-Switch-Proto-Board/tree/master or you can purchase this development board from www.forcetronics.com


Download Eagles files from GitHub: https://github.com/ForceTronics/AC-Switch-Proto-Board

*********************************Arduino code shown in the video********
//This sketch is used to control Thyristor that is used as a switch to turn on and off an AC line powered light. //This code is free for all to use
int8_t dig = 0; //default is high for light off

void setup() {
  //for controlling Thyristor
  pinMode(7, OUTPUT); //set pin to output so it can sink current from optoisolator
  digitalWrite(7, HIGH); //when high the thyristor is off or open
}

void loop() {
  delay(3000); //light turns on / off every 2 seconds
  togLight(); //call function to turn light on / off using digital pin
}

void togLight() {
  if(dig) { 
     digitalWrite(7, HIGH); //turn off light
     dig = 0; //toggle dig value
  }
  else {  
     digitalWrite(7, LOW); //turn light on
     dig = 1; 
   }
}



Tuesday, December 22, 2015

Building a Wireless Sensor Network with the nRF24L01 Part 2

In part 2 we focus on powering our wireless sensor node. We talk about batteries, battery sizing, estimating battery life, and battery monitoring. If you have any feedback or questions use the comments section below.


Updated Schematic for Part 2


Monday, December 7, 2015

Building a Wireless Sensor Network with the nRF24L01 Part 1

This is part 1 in a series where we look at how to build a large wireless network using Arduino and the nRF24L01+ Transceiver Modules. At the end of this series you will have a reference design for a wireless sensor development board and the code needed to turn the wireless sensor developments boards into a network. You will be able purchase all the hardware for this project at my site: www.forcetronics.com


Initial Hardware Design

Monday, November 23, 2015

Getting Started with the Atmel Xplained Mini with the ATmega168PB MCU

In this video we give you an overview of the Atmel Xplained Mini which is a development board for the ATmega168PB microcontroller. In the video we cover how to load a simple "Blink" program onto the Xplained Mini with Atmel Studio and how the development board is compatible with Arduino Shields. The video is presented from the standpoint of an Arduino user. You can access the code from the video below.



//**************************Atmel Studio Code****************************
/*
 * ATmega168PB Example.c
 *
 * Created: 11/21/2015 4:59:24 PM
 * Author : ForceTronics
 */ 

#define F_CPU 16000000UL //Set the clock frequency
#include <avr/io.h> //call IO library
#include <util/delay.h> //call delay library

int main(void)
{
DDRB |= (1<<DDB5); //Set Port B 5 or PB5 or PCINT5 or pin 17 to output (1 is output and 0 is input)
while(1)
{
/*
PORTB |= (1<<PORTB5);    //Set PB5 to 1 which is high (LED on)
_delay_ms(1000);        //Delay for 1000ms or 1 sec
PORTB &= ~(1<<PORTB5);    //Set PB5 to 0 which is low (LED off)
_delay_ms(1000);        //Delay for 1000ms or 1 sec
*/
PINB |= (1<<PINB5);
_delay_ms(1000);        //Delay for 1000ms or 1 sec
}
}



Monday, November 16, 2015

Using the LM317 Voltage Regulator

In this video we give you an overview of the LM317 Voltage Regulator and how to configure it. The LM317 is popular voltage regulator among makers because of its low cost and its adjustable output voltage. You can purchase the LM317 at www.forcetronics.com


Friday, October 30, 2015

Building a Arduino Uno Compatible Circuit

Ever want to remove the microcontroller off the Arduino board to better integrate it into your project or design. In this video we do just that with Atmel ATmega 328P MCU found on the Arduino Uno. We will look at the bare bones circuit setup needed to run the 328P as well as how to still program it with the Arduino IDE. All the parts shown in this video can be purchased from forcetronics.com.




Tuesday, October 20, 2015

Building an Arduino Shield and Proto Board for the nRF24L01 Transceiver

The nRF24L01+ Transceiver is a great low cost way to add wireless capability to any project. But the down side of the nRF24L01+ is it can be a hassle to prototype with. In this video we look at how to build an Arduino shield and a mini proto board for the nRF24L01+. You can also purchase the shield and mini proto board covered in the video at forcetronics.com.



To Access the Eagle PCB files:
//*****************************Arduino Code for Transmitter***********************
//This sketch is from a tutorial video on the ForceTronics YouTube Channel. The tutorial discusses how to build a 
//shield and a prototyping board for the nRF24L01 Transceiver Module.
//the code was leverage from Ping pair example at http://tmrh20.github.io/RF24/pingpair_ack_8ino-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t pAddress = 0xB00B1E5000LL;   // Radio pipe addresses for the 2 nodes to communicate.

void setup()  
{
  Serial.begin(57600);   //start serial to communicate process
  wirelessSPI.begin();            //Start the nRF24 module
  wirelessSPI.setAutoAck(1);                    // Ensure autoACK is enabled so rec sends ack packet to let you know it got the transmit packet payload
  wirelessSPI.setRetries(5,15);                 // Sets up retries and timing for packets that were not ack'd, current settings: smallest time between retries, max no. of retries
  wirelessSPI.openWritingPipe(pAddress);        // pipe address that we will communicate over, must be the same for each nRF24 module
  wirelessSPI.stopListening();
}

void loop()  
{
   byte t = analogRead(0);//note that we can cast the ADC value to a byte because we know the temp sensor is not going to return a value higher than 255
   if (!wirelessSPI.write(&t, 1 )){  //if the send fails let the user know over serial monitor
       Serial.println("packet delivery failed");      
   }
    delay(1000);
}

//*****************************Arduino Code for Receiver***********************
//This sketch is from a tutorial video on the ForceTronics YouTube Channel. The tutorial discusses how to build a 
//shield and a prototyping board for the nRF24L01 Transceiver Module.
//the code was leverage from Ping pair example at http://tmrh20.github.io/RF24/pingpair_ack_8ino-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte bVal; //used to store ADC value payload from transmit module, the ADC value will be < 256 so it will fit in a byte
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI) 
const uint64_t pAddress = 0xB00B1E5000LL;  //Create a pipe addresses for the 2 nodes to communicate over, the "LL" is for LongLong type

void setup()   
{
  Serial.begin(57600);  //start serial to communicate process
  wirelessSPI.begin();  //Start the nRF24 module
  wirelessSPI.setAutoAck(1);                    // Ensure autoACK is enabled, this means rec send acknowledge packet to tell xmit that it got the packet with no problems
  wirelessSPI.openReadingPipe(1,pAddress);      //open pipe o for recieving meassages with pipe address
  wirelessSPI.startListening();                 // Start listening for messages
}

void loop()  
{   
   //loop until all of the payload data is recieved, for this example loop should only run once
    while(wirelessSPI.available()){ 
     wirelessSPI.read( &bVal, 1 ); //read one byte of data and store it in bVal variable
     Serial.print("Temperature at transmitter is "); 
     Serial.print(calculateTempF(calculateArduinoVolt(bVal))); //convert the ADC value to a voltage value and than to a temperature value in F
     Serial.println(" F");
    }
 
  delay(200);    
}

//this function calculates temp in F from TMP36 temp sensor
float calculateTempF(float v1) { 
 float temp = 0;
 //calculate temp in C, .75 volts is 25 C. 10mV per degree
 if (v1 < .75) { temp = 25 - ((.75-v1)/.01); } //if below 25 C
 else if (v1 == .75) {temp = 25; }
 else { temp = 25 + ((v1 -.75)/.01); } //if above 25
 //convert to F
 temp =((temp*9)/5) + 32;
 return temp;
}

//This function takes an Arduino analog pin reading and converts it to a voltage value
float calculateArduinoVolt(int val) {
 float volt = (float)val * (5.0 / 1023.0); //convert ADC value to voltage
 return volt;
}



Thursday, October 1, 2015

Arduino Zero DAC Overview and Waveform Generator Example

In this video we take a look at the digital to analog converter (DAC) on the Arduino Zero. We will look at a simple example how to use the DAC and then we will look at a more complex example that turns the DAC into a pseudo waveform generator. You can find the code from this video below.


//***************ZeroDACExample Sketch*******************************
//This sketch provides an example on using the DAC on the Arduino Zero.
//It was used in a video tutorial on the ForceTronics YouTube Channel.
//This code is free and open for anybody to use and modify at their own risk

void setup()
{
  Serial.begin(57600); //start serial communication
  analogWriteResolution(10); //set the Arduino DAC for 10 bits of resolution (max)
  analogReadResolution(12); //set the ADC resolution to 12 bits, default is 10
  
  //Get user entered voltage, convert to DAC value, output DAC value
  analogWrite(A0,setDAC(getVoltValue()));
}

void loop()
{
  delay(2000);
  Serial.println();
  Serial.print("Measured voltage value is ");
  Serial.println(convertToVolt(analogRead(A1))); //Read value at ADC pin A1 and print it

}

//this function converts a user entered voltage value into a 10 bit DAC value 
int setDAC(float volt) {
//formula for calculating DAC output voltage Vdac = (dVal / 1023)*3.3V
return (int)((volt*1023)/3.3);
}

//this function gets the user entered DAC voltage value from serial monitor
float getVoltValue() {
float v = 0; //variable to store voltage 
Serial.println("Enter the voltage you want the DAC to output (range 0V to 3.3V)");
v = readParameter();
if (v < 0 || v > 3.3) v = 0; //check to make sure it is between 0 and 3.3V
Serial.print("DAC voltage set to ");
Serial.println(v);
Serial.println("Outputting DAC value........");
return v;
}

//waits for serial data and reads it in. This function reads in the parameters
// that are entered into the serial terminal
float readParameter() {
while(!Serial.available()); //Wait for user to enter setting
return Serial.parseFloat(); //get int that was entered on Serial monitor
}

//This function takes and ADC integer value (0 to 4095) and turns it into a voltage level. The input is the measured 12 bit ADC value.
float convertToVolt(int aVAL) {
return (((float)aVAL/4095)*3.3); //formula to convert ADC value to voltage reading
}

//***************ZeroWaveGen Sketch**************************************
//This sketch generates a sine wave on the Arduino Zero DAC based on user entered sample count and sample rate
//It was used in a tutorial video on the ForceTronics YouTube Channel. This code can be used and modified freely
//at the users own risk
volatile int sIndex; //Tracks sinewave points in array
int sampleCount = 100; // Number of samples to read in block
int *wavSamples; //array to store sinewave points
uint32_t sampleRate = 1000; //sample rate of the sine wave

void setup() {
  analogWriteResolution(10); //set the Arduino DAC for 10 bits of resolution (max)
  getSinParameters(); //get sinewave parameters from user on serial monitor
  
  /*Allocate the buffer where the samples are stored*/
  wavSamples = (int *) malloc(sampleCount * sizeof(int));
  genSin(sampleCount); //function generates sine wave
}

void loop() {
  sIndex = 0;   //Set to zero to start from beginning of waveform
  tcConfigure(sampleRate); //setup the timer counter based off of the user entered sample rate
  //loop until all the sine wave points have been played
  while (sIndex<sampleCount)
  { 
//start timer, once timer is done interrupt will occur and DAC value will be updated
    tcStartCounter(); 
  }
  //disable and reset timer counter
  tcDisable();
  tcReset();
}

//This function generates a sine wave and stores it in the wavSamples array
//The input argument is the number of points the sine wave is made up of
void genSin(int sCount) {
const float pi2 = 6.28; //2 x pi
float in; 

for(int i=0; i<sCount;i++) { //loop to build sine wave based on sample count
in = pi2*(1/(float)sCount)*(float)i; //calculate value in radians for sin()
wavSamples[i] = ((int)(sin(in)*511.5 + 511.5)); //Calculate sine wave value and offset based on DAC resolution 511.5 = 1023/2
}
}

//This function handles getting and setting the sine wave parameters from 
//the serial monitor. It is important to use the Serial.end() function
//to ensure it doesn't mess up the Timer counter interrupts later
void getSinParameters() {
Serial.begin(57600);
Serial.println("Enter number of points in sine wave (range 10 to 1000)");
sampleCount = readParameter();
if (sampleCount < 10 || sampleCount > 1000) sampleCount = 100;
Serial.print("Sample count set to ");
Serial.println(sampleCount);
Serial.println("Enter sample rate or samples per second for DAC (range 1 to 100k)");
sampleRate = readParameter();
if (sampleRate < 1 || sampleRate > 100000) sampleRate = 10000;
Serial.print("Sample rate set to ");
Serial.println(sampleRate);
Serial.println("Generating sine wave........");
Serial.end();
}

//waits for serial data and reads it in. This function reads in the parameters
// that are entered into the serial terminal
int readParameter() {
while(!Serial.available());
return Serial.parseInt(); //get int that was entered on Serial monitor
}

// Configures the TC to generate output events at the sample frequency.
//Configures the TC in Frequency Generation mode, with an event output once
//each time the audio sample frequency period expires.
 void tcConfigure(int sampleRate)
{
// Enable GCLK for TCC2 and TC5 (timer counter input clock)
GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ;
while (GCLK->STATUS.bit.SYNCBUSY);

tcReset(); //reset TC5

// Set Timer counter Mode to 16 bits
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
// Set TC5 mode as match frequency
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
//set prescaler and enable TC5
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;
//set TC5 timer counter based off of the system clock and the user defined sample rate or waveform
TC5->COUNT16.CC[0].reg = (uint16_t) (SystemCoreClock / sampleRate - 1);
while (tcIsSyncing());

// Configure interrupt request
NVIC_DisableIRQ(TC5_IRQn);
NVIC_ClearPendingIRQ(TC5_IRQn);
NVIC_SetPriority(TC5_IRQn, 0);
NVIC_EnableIRQ(TC5_IRQn);

// Enable the TC5 interrupt request
TC5->COUNT16.INTENSET.bit.MC0 = 1;
while (tcIsSyncing()); //wait until TC5 is done syncing 
}

//Function that is used to check if TC5 is done syncing
//returns true when it is done syncing
bool tcIsSyncing()
{
  return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY;
}

//This function enables TC5 and waits for it to be ready
void tcStartCounter()
{
  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; //set the CTRLA register
  while (tcIsSyncing()); //wait until snyc'd
}

//Reset TC5 
void tcReset()
{
  TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
  while (tcIsSyncing());
  while (TC5->COUNT16.CTRLA.bit.SWRST);
}

//disable TC5
void tcDisable()
{
  TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
  while (tcIsSyncing());
}

void TC5_Handler (void)
{
  analogWrite(A0, wavSamples[sIndex]);
  sIndex++;
  TC5->COUNT16.INTFLAG.bit.MC0 = 1;
}

Saturday, September 19, 2015

Debugging with the Arduino Zero

In this video we look at how to do debugging with the Arduino Zero. The Arduino Zero has a lot of great capabilities and features. One of those great features is it has a built-in hardware debugger. In this video we will look at how to use the debugger and the software you need to go with it.




//***************Arduino Code from Video**********************************
/*
This code was used for a tutorial video on the ForceTronics YouTube Channel that showed
how to do debugging with the Arduino Zero and Atmel Studio. This code is free and open
for anybody to use or modify
 */
int ranNum; //global variable to hold random number

void setup() {
  randomSeed(analogRead(A0)); //seed value for random number generator
  pinMode(13, OUTPUT); // initialize digital pin 13 as an output.
}

void loop() {
  
  ranNum = random(0,100);   //generate a random number between zero and 100
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

Wednesday, September 2, 2015

Contracting and Consulting Services for Open Source Hardware Design

This video provides an overview of ForceTronics LLC's contracting and consulting services. Whether you are a maker, entrepreneur, or a startup Forcetronics Contracting and Consulting Services can help turn your idea into reality leveraging the power of open source hardware.






If you are interested contact me on twitter or email:
  • Twitter: @ForceTronics
  • Email: forcetronics@gmail.com
Put “Contracting Services” or “Consulting Services” in the subject line



Tuesday, August 11, 2015

Building Your Own AVR / Arduino Internet of Things (IoT) Development Board Part 5

Welcome to the final installment of building your own AVR / Arduino compatible internet of things (IoT) development board. In part 5 we open up our new PCBs and build them up. We then do some testing to make sure everything is working correctly. Spoiler alert, this video has a happy ending with a working Arduino compatible board with Bluetooth 4.0 built-in. Below you will find a link to the Eagle files and the Arduino code for the test sketch.



Link to download Eagle files including: library file, project files, and Gerber files:
https://dl.dropboxusercontent.com/u/26591541/AVR_IoT_Board_Eagle_Files_8_8_15.zip


*******************Arduino Test Sketch************************************
//This sketch is to test a DIY Arduino compatiable board with Bluetooth 4.0 on it
//the board is targeted IoT applications. Details can be found of the ForceTronics 
//YouTube channel. This code is open for anybody to use and modify

int wValue = 1; //variable to hold write value (high or low)

void setup() {
   Serial.begin(115200); //start serial
}

void loop() {
  delay(1000);
  setPinMode(OUTPUT, INPUT); //set D2 to D7 as outputs, and D8 to D13 to inputs
  setDigWrite(false, wValue); //set group of pins to write and write high or low
  Serial.print("D2 thru D7 writing "); 
  Serial.println(wValue);
  Serial.println("D8 thru D13 reading the following values....");
  printDigPins(true); //print what dig pins read
  delay(1000);
  setPinMode(INPUT, OUTPUT); //set D2 to D7 as intputs, and D8 to D13 to outputs
  setDigWrite(true, wValue); //set group of pins to write and write high or low
  Serial.print("D8 thru D13 writing "); 
  Serial.println(wValue);
  Serial.println("D2 thru D7 reading the following values....");
  printDigPins(false); //print what dig pins read
  
  delay(1000);
  adcReads(); //read each ADC pin and print result
  
  if(wValue) wValue = 0; //toggle digital write value
  else wValue = 1;
  delay(1000);
}

//function sets D2 thru D7 to input / output and D8 thru D13 to input / output
void setPinMode(int smallMode, int bigMode) {
  for(int i=0;i<6;i++) {
    pinMode((i+2), smallMode);
    pinMode((i+8), bigMode);
  }  
}

//Writes high or low to group of digital pins
void setDigWrite(bool big, int state) {
  if(big) {
    for(int i=0;i<6;i++) {
      digitalWrite((i+8), state);
    }
  }
  else {
    for(int i=0;i<6;i++) {
      digitalWrite((i+2), state);
    }
  }
}

//does digital read on group of digital pins and prints results
void printDigPins(bool big) {
  if(big) {
    for(int i=0;i<6;i++) {
      Serial.print("Value at pin D");
      Serial.print((i+8));
      Serial.print(" --> ");
      Serial.println(digitalRead((i+8)));
    }
  }
  else {
    for(int i=0;i<6;i++) {
      Serial.print("Value at pin D");
      Serial.print((i+2));
      Serial.print(" --> ");
      Serial.println(digitalRead((i+2)));
    }
  }
}


//Reads each ADC pin and prints result
void adcReads() {
  for(int i=0; i<6; i++) {
    Serial.print("ADC value at Pin A");
    Serial.print(i);
    Serial.print(" --> ");
    Serial.println(analogRead(i));
  }
}

Sunday, August 2, 2015

Building a Not Gate from a Transistor

In this video we take a brief look at how a transistor works and how to use it as a not gate or an digital logic inverter. We look at an example with Arduino using both an NPN and a PNP bipolar junction transistor as a not gate



//***********Arduino Code ******************************************
//This example code was used on the Forcetronics YouTube Channel to demonstrate how to 
//make an inverter or not gate using an NPN and PNP transistor

const int NPN = 2; //create variable for NPN base 
const int PNP = 3; //create variable for PNP base
const int NPNRead = 4; //create variable to read NPN
const int PNPRead = 5; //create variable to read PNP

void setup() {
  pinMode(NPN, OUTPUT);   // set pin to output
  pinMode(PNP, OUTPUT);   // set pin to output
  pinMode(NPNRead, INPUT);   // set pin to input
  pinMode(PNPRead, INPUT);   // set pin to input
  Serial.begin(9600); //start serial comm
}

void loop() {
  digitalWrite(NPN, LOW);   // set NPN base to low
  digitalWrite(PNP, LOW);   // set PNP base to low
  Serial.println("Base of NPN and PNP is set to Low");
  Serial.print("NPN reads ");
  Serial.println(digitalRead(NPNRead)); //read and print value at NPN digital pin
  Serial.print("PNP reads ");
  Serial.println(digitalRead(PNPRead)); //read and print value at PNP digital pin
  Serial.println();
  delay(1000);
  digitalWrite(NPN, HIGH);   // set NPN base to high
  digitalWrite(PNP, HIGH);   // set PNP base to high
  Serial.println("Base of NPN and PNP is set to High");
  Serial.print("NPN reads ");
  Serial.println(digitalRead(NPNRead)); //read and print value at NPN digital pin
   Serial.print("PNP reads ");
  Serial.println(digitalRead(PNPRead)); //read and print value at PNP digital pin
  Serial.println();
  delay(1000);
}

Tuesday, July 21, 2015

Using a Transistor as a Switch

In this video we cover briefly what a transistor is and discuss how to use them as an electrical switch (DC only). As a demonstration we use an Arduino to switch on and off an NPN transistor and a PNP transistor.



//************************Arduino Code ******************************
//This example code was used on the Forcetronics YouTube Channel to demonstrate how to
//make an inverter or not gate using an NPN and PNP transistor. This code is open for
//anybody to use or modify

const int BJT = 2; //create variable to control the base of NPN and PNP

void setup() {
  pinMode(BJT, OUTPUT);   // set it as digital output
}

void loop() {
  digitalWrite(BJT, LOW);   // set base of NPN and PNP to low
  delay(1000);
  digitalWrite(BJT, HIGH);   // set base of NPN and PNP to high
  delay(1000);
}

Friday, July 10, 2015

Building Your Own AVR / Arduino Internet of Things (IoT) Development Board Part 4

This is part 4 in a 5 part series where we build our own AVR / Arduino Internet of Things (IoT) development board, yay! In this part we will do the PCB layout and discuss how to get our PCB manufactured.


Download Eagle Files



Eagle Parts and Libraries
Libraries Used:
•Atmega 328P --> Library: SparkFun-DigitalIC Device: ATMEGA328P_PDIP
•LM317 --> Library: linear>*317 Device:317T
•Resonator ZTT16.0MHz --> Library: Adafruit Device: CERMOSCILL-THM (CERMOSCILL)
•Ceramic Cap --> Library: rcl > C-EU Device: C-EU050-030X075
•Electrolytic cap --> Library: rcl > CPOL-EU Device: CPOL-EUE2.5-6
•Resistor --> Library: resistor Device: R-EU_0207/10 (R-EU_) Package: 0207/10
•Reset switch --> Library: switch-omron Device: 10-XX
•LED --> Library: led Device: LED5MM (LED)
•Potentiometer --> Library: rcl > R-TRIMM Device: R-TRIMMT93YA
Note: Sparkfun and Adafruit libraries did not come with Eagle, but you can find them on their websites

Parts I made (included in files linked to my blog):
•ForceTronic.lbr --> All header and pin holes and 2.1mm DC Jack
•BLE_Micro_Module.lbr --> BLE Micro

Monday, July 6, 2015

Building Your Own AVR / Arduino Internet of Things (IoT) Development Board Part 3

This is part 3 in a 5 part series where we build our own AVR / Arduino Internet of Things (IoT) development board, yay! In this part we will finalize our design schematic and parts list so we are ready to do PCB layout in part 4.



Final Design Schematic:


Bill of Materials:
  • Atmega 328P MCU (Dip Package)
  • 16MHz resonator
  • BLE Micro from DFRobot or equivalent
  • LM317 Voltage Regulator
  • Resistors (Ohms): 10k, 2x 1k, 2x 300, 1k POTENTIOMETER or 500
  • Capacitors: 4x 100nF (Ceramic) and 1uF (electrolytic)
  • LED 5mm (any color you want)
  • 0.1” male pins
  • 2x 0.1” 2x4 female header (optional)
  • 4x 0.1” pin jumpers
  • DC Power Jack (+ pin is 2.1mm) 
  • 13uH Inductor (optional)
  • Female pin headers: 6 pin, 2x 8 pin, 10 pin
  • 28 pin DIP Socket (optional): part # 4828-3004-CP

Wednesday, June 17, 2015

Building Your Own AVR / Arduino Internet of Things (IoT) Development Board Part 2

This is part 2 in a 5 part series where we build our own AVR / Arduino Internet of Things (IoT) development board, yay! In this part we add the Arduino bootloader to our Atmega 328p as well as build and test a prototype of our design.



BLE Micro Shield Eagle Files 1.0 version (use at your own risk):
https://dl.dropboxusercontent.com/u/26591541/BLE%20Shield.zip


//*******************Arduino Code**********************************************
/*
  This sketch is part of a video tutorial on the ForceTronics YouTube Channel for Building Your AVR/Arduino IoT Development Board 
  which uses a Atmega 328p and a Bluetooth low energy module. 
  The bluetooth module is connected to an Arduino and the Arduino is connected to an LED. 

  This code is in the public domain.
 */

// Pin 13 has a LED connected to it
int led = 13;

// the setup routine runs once when you press reset:
void setup() {
  
  Serial.begin(115200);
  // initialize the digital pin as an output and set it low initially
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

// the loop routine runs over and over again forever:
void loop() {
  delay(30);
  String t; //create an empty string to store messages from Android
  while(Serial.available()) { //keep reading bytes while they are still more in the buffer
    t += (char)Serial.read(); //read byte, convert to char, and append it to string
  }
  
  if(t.length()) { //if string is not empty do the following
    if(t == "on") { //if the string is equal to "on" then turn LED on
      digitalWrite(led, HIGH); //Set digital pin to high to turn LED on
      Serial.write("LED is on"); //Tell the Android app that the LED was turned on
    }
    else if (t == "off") { 
      digitalWrite(led, LOW);  
      Serial.write("LED is off");
    } // turn the LED off by making the voltage LOW
  }
}

Sunday, June 7, 2015

Intro to Bluetooth Low Energy (BLE) and the BLE Micro

In this video we will take a look at Bluetooth Low Energy or Bluetooth Smart and compare it to classic Bluetooth. From there we will look at how to get started with the BLE Micro module and look at how to communicate with it from an iOS device and another BLE Micro Module.




************************Arduino Code****************************************
/*
  This sketch is part of a video tutorial on the ForceTronics YouTube Channel for using the BLE Micro module which uses Bluetooth low energy. 
  The bluetooth module is connected to an Arduino and the Arduino is connected to an LED. 

  This code is in the public domain.
 */

// Pin 7 has a LED connected to it
int led = 7;

// the setup routine runs once when you press reset:
void setup() {
  
  Serial.begin(115200);
  // initialize the digital pin as an output and set it low initially
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

// the loop routine runs over and over again forever:
void loop() {
  delay(30);
  String t; //create an empty string to store messages from Android
  while(Serial.available()) { //keep reading bytes while they are still more in the buffer
    t += (char)Serial.read(); //read byte, convert to char, and append it to string
  }
  
  if(t.length()) { //if string is not empty do the following
    if(t == "on") { //if the string is equal to "on" then turn LED on
      digitalWrite(led, HIGH); //Set digital pin to high to turn LED on
      Serial.write("LED is on"); //Tell the Android app that the LED was turned on
    }
    else if (t == "off") { 
      digitalWrite(led, LOW);  
      Serial.write("LED is off");
    } // turn the LED off by making the voltage LOW
  }
}

Tuesday, June 2, 2015

Building Your Own AVR / Arduino Internet of Things (IoT) Development Board Part 1

In this 5 part video series we will build our own AVR / Arduino Internet of Things (IoT) development board. We will go from a design concept to prototyping our design to PCB layout of our design all the way to a tested and finished development board.


Example parts order for this project (please note that this does not include all the parts)






Wednesday, May 20, 2015

Reducing the Power Consumption of the nRF24L01 Transceiver

In this video we take a look at the power needs or power profile of the nRF24L01+ Transceiver. We discuss how much power it draws in each mode and how to reduce or optimize its power consumption for battery powered projects or designs. Finally we pair the nRF24L01 with an Arduino utilizing sleep mode and look at their combined power profile.



************Arduino and nRF24L01 Low Power Example Sketch*************
#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <avr/sleep.h>
#include <avr/wdt.h> 

/*WDT BYTE variables for setting timer value
     WDTO_15MS, WDTO_30MS, WDTO_60MS, WDTO_120MS, WDTO_250MS, WDTO_500MS, WDTO_1S, WDTO_2S, WDTO_4S, WDTO_8S */

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t wAddress = 0xB00B1E50D2LL;              // Pipe to write or transmit on
const uint64_t rAddress = 0xB00B1E50B1LL;  //pipe to recive data on

void setup() {
  randomSeed(analogRead(0)); //create unique seed value for random number generation
  wirelessSPI.begin();            //Start the nRF24 module
  wirelessSPI.setRetries(15,10);
  wirelessSPI.openWritingPipe(wAddress);        //open writing or transmit pipe
  wirelessSPI.openReadingPipe(1,rAddress);  //open reading or recieve pipe
  wirelessSPI.stopListening(); //go into transmit mode
}

void loop() {
   byte randNumber = (byte)random(11); //generate random guess between 0 and 10 
    if (!wirelessSPI.write(&randNumber, 1)){  //if the write fails
      // delivery failed      
     }
     
   delay(30); //delay for short time in normal mode
   wirelessSPI.powerDown(); //put nRF24L01 into power down mode
   delayWDT(WDTO_30MS);   // Use WDT sleep delay function, argument is byte variable from WDT Library
   wirelessSPI.powerUp(); //power up the nRF24
}

//This function serves as a power saving delay function. The argument is a Byte type variable that is used to set the delay time
//The function sets up sleep mode in power down state. The function then sets up the WDT timer in interrupt mode and sets it.
//It then puts the Arduino to sleep for the set time. Upon wake up the WDT and sleep mode are shut off
void delayWDT(byte timer) {
  sleep_enable(); //enable the sleep capability
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set the type of sleep mode. Default is Idle
  ADCSRA &= ~(1<<ADEN); //Turn off ADC before going to sleep (set ADEN bit to 0)
  WDTCSR |= 0b00011000;    //Set the WDE bit and then clear it when set the prescaler, WDCE bit must be set if changing WDE bit   
  WDTCSR =  0b01000000 | timer; //Or timer prescaler byte value with interrupt selectrion bit set
  wdt_reset(); //Reset the WDT 
  sleep_cpu(); //enter sleep mode. Next code that will be executed is the ISR when interrupt wakes Arduino from sleep
  sleep_disable(); //disable sleep mode
  ADCSRA |= (1<<ADEN); //Turn the ADC back on
}

//This is the interrupt service routine for the WDT. It is called when the WDT times out. 
//This ISR must be in your Arduino sketch or else the WDT will not work correctly
ISR (WDT_vect) 
{
  wdt_disable();
   MCUSR = 0; //Clear WDT flag since it is disabled, this is optional

}  // end of WDT_vect

Saturday, May 9, 2015

Creating a nRF24L01 Transceiver Network

In this video we will look at how to create an nRF24L01 Transceiver module network (more than two). This is useful if you want to build a wireless sensor network or some type of wireless automation system that has multiple wireless nodes.



***************************Arduino Code for Receiver*******************************
//This sketch is from a tutorial video for networking more than two nRF24L01 tranciever modules on the ForceTronics YouTube Channel
//the code was leverage from the following code http://maniacbug.github.io/RF24/starping_8pde-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte daNumber = 0; //The number that the transmitters are trying to guess
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI) 
const uint64_t rAddress[] = {0xB00B1E50D2LL, 0xB00B1E50C3LL};  //Create pipe addresses for the 2 nodes to recieve data, the "LL" is for LongLong type
const uint64_t wAddress[] = {0xB00B1E50B1LL, 0xB00B1E50A4LL};  //Create pipe addresses for the 2 nodes to transmit data, the "LL" is for LongLong type

void setup()   
{
  randomSeed(analogRead(0)); //create unique seed value for random number generation
  daNumber = (byte)random(11); //Create random number that transmitters have to guess
  Serial.begin(57600);  //start serial to communication
  Serial.print("The number they are trying to guess is: "); 
  Serial.println(daNumber); //print the number that they have to guess
  Serial.println();
  wirelessSPI.begin();  //Start the nRF24 module
  wirelessSPI.openReadingPipe(1,rAddress[0]);      //open pipe o for recieving meassages with pipe address
  wirelessSPI.openReadingPipe(2,rAddress[1]);      //open pipe o for recieving meassages with pipe address
  wirelessSPI.startListening();                 // Start listening for messages
}

void loop()  
{   
    byte pipeNum = 0; //variable to hold which reading pipe sent data
    byte gotByte = 0; //used to store payload from transmit module
    
    while(wirelessSPI.available(&pipeNum)){ //Check if recieved data
     wirelessSPI.read( &gotByte, 1 ); //read one byte of data and store it in gotByte variable
     Serial.print("Recieved guess from transmitter: "); 
     Serial.println(pipeNum); //print which pipe or transmitter this is from
     Serial.print("They guess number: ");
     Serial.println(gotByte); //print payload or the number the transmitter guessed
     if(gotByte != daNumber) { //if true they guessed wrong
      Serial.println("Fail!! Try again."); 
     }
     else { //if this is true they guessed right
      if(sendCorrectNumber(pipeNum)) Serial.println("Correct! You're done."); //if true we successfully responded
      else Serial.println("Write failed"); //if true we failed responding
     }
     Serial.println();
    }

  delay(200);    
}

//This function turns the reciever into a transmitter briefly to tell one of the nRF24s
//in the network that it guessed the right number. Returns true if write to module was
//successful
bool sendCorrectNumber(byte xMitter) {
    bool worked; //variable to track if write was successful
    wirelessSPI.stopListening(); //Stop listening, stop recieving data.
    wirelessSPI.openWritingPipe(wAddress[xMitter-1]); //Open writing pipe to the nRF24 that guessed the right number
    if(!wirelessSPI.write(&daNumber, 1))  worked = false; //write the correct number to the nRF24 module, and check that it was recieved
    else worked = true; //it was recieved
    wirelessSPI.startListening(); //Switch back to a reciever
    return worked;  //return whether write was successful
}

***************************Arduino Code for Transmitter 1****************************
//This sketch is from a tutorial video for networking more than two nRF24L01 tranciever modules on the ForceTronics YouTube Channel
//the code was leverage from the following code http://maniacbug.github.io/RF24/starping_8pde-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte counter = 1; //used to count the packets sent
bool done = false; //used to know when to stop sending packets
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t wAddress = 0xB00B1E50D2LL;              // Pipe to write or transmit on
const uint64_t rAddress = 0xB00B1E50B1LL;  //pipe to recive data on

void setup()  
{
  Serial.begin(57600);   //start serial to communicate process
  randomSeed(analogRead(0)); //create unique seed value for random number generation
  wirelessSPI.begin();            //Start the nRF24 module
  wirelessSPI.openWritingPipe(wAddress);        //open writing or transmit pipe
  wirelessSPI.openReadingPipe(1,rAddress);  //open reading or recieve pipe
  wirelessSPI.stopListening(); //go into transmit mode
}


void loop()  
{
   if(!done) { //true once you guess the right number
     byte randNumber = (byte)random(11); //generate random guess between 0 and 10
   
    if (!wirelessSPI.write( &randNumber, 1 )){  //if the write fails let the user know over serial monitor
         Serial.println("Guess delivery failed");      
     }
     else { //if the write was successful 
          Serial.print("Success sending guess: ");
          Serial.println(randNumber);
       
        wirelessSPI.startListening(); //switch to recieve mode to see if the guess was right
        unsigned long startTimer = millis(); //start timer, we will wait 200ms 
        bool timeout = false; 
        while ( !wirelessSPI.available() && !timeout ) { //run while no recieve data and not timed out
          if (millis() - startTimer > 200 ) timeout = true; //timed out
        }
    
        if (timeout) Serial.println("Last guess was wrong, try again"); //no data to recieve guess must have been wrong
        else  { //we recieved something so guess must have been right
          byte daNumber; //variable to store recived value
          wirelessSPI.read( &daNumber,1); //read value
          if(daNumber == randNumber) { //make sure it equals value we just sent, if so we are done
            Serial.println("You guessed right so you are done");
            done = true; //signal to loop that we are done guessing
          }
          else Serial.println("Something went wrong, keep guessing"); //this should never be true, but just in case
        }
        wirelessSPI.stopListening(); //go back to transmit mode
      
     }
   }
    delay(1000);
}

***************************Arduino Code for Transmitter 2****************************
//This sketch is from a tutorial video for networking more than two nRF24L01 tranciever modules on the ForceTronics YouTube Channel
//the code was leverage from the following code http://maniacbug.github.io/RF24/starping_8pde-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
bool done = false; //used to know when to stop sending guesses
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t wAddress = 0xB00B1E50C3LL;  //pipe for writing or transmitting data
const uint64_t rAddress = 0xB00B1E50A4LL;  //pipe for reading or recieving data

void setup()  
{
  Serial.begin(57600);   //start serial to communicate process
  randomSeed(analogRead(0)); //create unique seed value for random number generation
  wirelessSPI.begin();            //Start the nRF24 module
  wirelessSPI.openWritingPipe(wAddress);    // setup pipe to transmit over
  wirelessSPI.openReadingPipe(1,rAddress);  //set up pipe to recieve data
  wirelessSPI.stopListening();  //turn off recieve capability so you can transmit
}


void loop()  
{
  if(!done) { //true once you guess the right number
     byte randNumber = (byte)random(11); //generate random guess between 0 and 10
   
    if (!wirelessSPI.write( &randNumber, 1 )){  //if the write fails let the user know over serial monitor
         Serial.println("Guess delivery failed");      
     }
     else { //if the write was successful 
          Serial.print("Success sending guess: ");
          Serial.println(randNumber);
       
        wirelessSPI.startListening(); //switch to recieve mode to see if the guess was right
        unsigned long startTimer = millis(); //start timer, we will wait 200ms 
        bool timeout = false; 
        while ( !wirelessSPI.available() && !timeout ) { //run while no recieve data and not timed out
          if (millis() - startTimer > 200 ) timeout = true; //timed out
        }
    
        if (timeout) Serial.println("Last guess was wrong, try again"); //no data to recieve guess must have been wrong
        else  { //we recieved something so guess must have been right
          byte daNumber; //variable to store recived value
          wirelessSPI.read( &daNumber,1); //read value
          if(daNumber == randNumber) { //make sure it equals value we just sent, if so we are done
            Serial.println("You guessed right so you are done");
            done = true; //signal to loop that we are done guessing
          }
          else Serial.println("Something went wrong, keep guessing"); //this should never be true, but just in case
        }
        wirelessSPI.stopListening(); //go back to transmit mode
      
     }
   }
    delay(1000);
}