Project tutorial
Flightduino 101

Flightduino 101 © Apache-2.0

A drone project that uses the Neural Pattern Recognition Module and other aspects of the Curie Module to advantage for creating a cool drone

  • 15,709 views
  • 3 comments
  • 36 respects

Components and supplies

Apps and online services

About this project

Making Friends with Arduino 101

This is the third Arduino in my collection of boards, so the unboxing and getting started with Arduino example sketches is now getting familiar. I was pleased with the BLE and accelerometer aspects of Arduino 101. I dowloaded a pdf for the Curie module and skimmed through it and then I saw something to get excited about!

A quote from the curie module pdf:

1.3.6 Pattern matching engine

• Parallel data recognition engine

• 128 parallel arithmetic units (Processing Element or PE) with 8-bit features per PE

• Two pattern matching algorithms:— K nearest neighbors (KNN)— Radial Basis Function (RBF)

• Two distance matching formulas:— Lsup— L1

• Constant recognition time

• Vector data: up to 128 bytes

• Classification status:— ID - identified, only one category matches— UNC - uncertain, more than one category matches— UNK- unknown, no match

• Support for up to 32,768 categories

• Supervised learning

• Save and restore network knowledge

• Three main operations supported:— Recognize a vector— Save the knowledge base from the network— Load the knowledge base to the network

I still had to do some internet searching to find more information about the pattern matching module.

I found this article which had some very useful links.

http://www.mouser.com/blog/arduino-101-pattern-matching-on-the-intel-quark-se-microcontroller

The most interesting link in the article:

http://www.general-vision.com/products/curieneurons/

This leads you to a free Arduino library for CurieNeurons. There is a "Pro" version of it for $19, but I will get started with the free version first.

Why Neural Networks?

I will cite a YouTube video, that probably answer the question better than I could any time real soon.

Why Neural Networks and Drones?

So Dr Randal Koene at the very end of the video suggests that we can build drones with help from neural networks.

So what sorts of problems are specially suited to solutions with neural networks?

Autonomous search and rescue drones , finding a clear path.

http://www.theverge.com/2016/2/11/10965414/autonomous-drones-deep-learning-navigation-mapping

Simpler Problems for this project

I am going to work on far more simple problem - A Landing Zone Orientation Detector

Not quite as bold as the vision problem mentioned in the link but I need to start on simpler pattern recognition problems.

Using CurieNeurons

Get the CurieNeurons Library found at the following link.

http://www.general-vision.com/software/curieneurons/

Unzip the CurieNeurons.zip file , then open the readme.txt file found in the CurieNeurons folder and follow the directions contained in the readme.txt file.

Landing Zone Oreintation Detector

The CurieNeurons will be used to detect the orientation of the drone over the landing pad. A complete implementation of this system would take far longer than the contest time period. So this work is a demonstration, or a proof of concept.

The need that motivates this detect the orientation of a drone landing pad is developed in a project proposal regarding the environmental problems caused by hazardous algae blooms (HABs).

https://www.hackster.io/37505/tethered-drone-for-environmental-monitoring-buoy-840692

The basic idea:

A unique pattern is chosen for the landing pad for the drone. In this demonstration I will use a smiley face. The length of a vector in the CurieNeuron is 128 bytes. So I am compressing the image from a camera to an 11 bit by 11 bit pattern which will be fed to the CurieNeurons for recognition.

In a more complete implementation there would be a whole system dedicated to finding the smiley face in a picture and converting it to the 11 bit by 11 bit pattern, but since that is complicated and also outside of the available development time I am having to skip that part. So I will use manually generated test patterns.

Some of you may be saying , he is skipping all the difficult parts of the system and only showing the CurieNeurons operating in their strength ( doing what they like to do ) . For those having such thoughts, the author salutes you as being wise and astute.

Here the smiley is twisted by 45 degrees. The gray pixels represent uncertain pixels. In the loading of the neuron vector black will be represented by 255. Uncertain pixels will be represented by 128. White pixels will be represented by 0.

I have really simplified things to fit the whole smiley face into the 128 byte CurieNeuron vector, In a more practical example a feature like the smile would be trained into the neurons at various angles. The eyes would be separately trained also. A "map" built up of the recognized much smaller features would be "read" by a higher level program that would determine the spatial orientation of the smiley face.

General Vision has chips with much larger counts of neurons than the Curie SoC which has 128 CurieNeurons . The more you work with the CurieNeurons the projects you design will probably cause you to use the larger chips to build your systems. But for now, we will simplify our design problem as needed to make do with 128 CurieNeurons available to use on Arduino 101.

So the CurieNeurons will be loader with eight patterns representing the smiley face in 8 orientations. Some experiments will be run where noise is injected into the test cases to see how much noise the system can tolerate.

I will load the CurieNeurons vectors by scanning the image left to right, from the top to the bottom of the bitmap. This is arbitrary and the CurieNeurons would work the same regardless of how the bitmap was scanned in.

I will modify one of the CurieNeuron demo programs to use the smiley bitmaps .

Here is output from the program.

Fading the image

The image will be faded on a pixel by pixel basis to gray. 100% fading would make all the pixels gray and stop the recognitions. We will see how much fading can occur before recognition stops.

So the original smiley with no twist can be faded 9% before recognition stops working. A 45 degree twisted smiley can be faded 14% before recognition stops. The really good news in all of this is that no false recognition of wrong orientation smileys occurred. That make a neural network person very happy!

The archives are included for both Arduino Sketches. I have also include the source for the Fading the Image test, so you can look at the source and hopefully see how easy it is to get started with CurieNeurons on the Arduino101. Have fun with the code!

Code

FlightDuino Arduino
First Experiments with CurieNeurons to recognize small 11 by 11 pixel images, import this archived Arduino Sketch and have fun with it.
No preview (download only).
Testing Flightduino with Faded Input ImagesArduino
Import the archive to work with fading the images
No preview (download only).
Faded Image SourceArduino
I thought you might like to look at the source before downloading the archive
//------------------------------------------------------------------------
// Flightduino is a modification of the CurieNeurons SimpleAcademicScript
// Refer to http://www.general-vision.com/documentation/TM_TestNeurons_SimpleScript.pdf
//
// Test Script to attempt to detect the orientation of a smiley face,
//  for possible use to detect a smiley face drone landing pad
//
//
// -----------------------------------------------------------------------
//
// The patterns are arrays of length LEN composed of identical values VAL
// They basically represent horizontal lines with different heights. This representation
// is easy to comprehend the distance between the learned lines (stored in the memory
// of the committed neurons) and a new input line
//
// In this script, the patterns to recognize are generated programatically to
// surround the learned patterns

#include <CurieNeurons.h>
CurieNeurons hNN;

byte VAL=11;
int neuronsAvailable, neuronsCommitted, neuronSize;
int ncr, dist, cat, aif, nid, nsr;
#define W   0   // white pixel is 0
#define G 127   // gray  pixel is 127
#define B 255   // black pixel is 255
#define LEN 121 // 11x11 pixel smiley face array;
byte pattern[LEN]={W,W,B,B,B,B,B,B,B,W,W,
                   W,B,W,W,W,W,W,W,W,B,W,
                   B,W,W,W,W,W,W,W,W,W,B,
                   B,W,W,B,W,W,W,B,W,W,B,
                   B,W,W,W,W,W,W,W,W,W,B,
                   B,W,W,W,W,B,W,W,W,W,B,
                   B,W,W,W,W,W,W,W,W,W,B,
                   B,W,W,B,W,W,W,B,W,W,B,
                   B,W,W,W,B,B,B,W,W,W,B,
                   W,B,W,W,W,W,W,W,W,B,W,
                   W,W,B,B,B,B,B,B,B,W,W}; // values must range between 0-255.
                   
byte pattern_t45[LEN]={W,W,G,B,G,G,G,B,G,W,W, // smiley face twisted 45 degrees counter clockwise
                       W,G,B,G,W,W,W,G,B,G,W, // gray for an uncertain half and half pixel
                       G,B,G,W,W,B,W,W,G,B,G,
                       B,G,W,W,W,W,W,W,W,G,B,
                       G,W,W,W,W,W,W,W,W,W,G,
                       G,W,B,W,W,B,W,W,B,W,G,
                       G,W,W,W,W,W,W,W,G,W,G,
                       B,G,W,W,W,W,W,B,G,G,B,
                       G,B,G,W,W,B,G,G,G,B,G,
                       W,G,B,G,W,W,W,G,B,G,W,
                       W,W,G,B,G,G,G,B,G,W,W}; // values must range between 0-255.
byte pattern_t90[LEN]; // smiley face twisted 90 degrees counter clockwise
byte pattern_t135[LEN]; // smiley face twisted 135 degrees counter clockwise
byte pattern_t180[LEN]; // smiley face twisted 180 degrees counter clockwise
byte pattern_t225[LEN]; // smiley face twisted 225 degrees counter clockwise
byte pattern_t270[LEN]; // smiley face twisted 270 degrees counter clockwise
byte pattern_t315[LEN]; // smiley face twisted 270 degrees counter clockwise                        
byte test_pattern[LEN];                       

#define K 3
int dists[K], cats[K], nids[K];
void fade(byte * src_ptr, byte * dst_ptr, int percent){ // percent should be 0 to 100
  int i,j;
  int temp_pixel;
  for(i=0;i<11;i++){
    for(j=0;j<11;j++){
      temp_pixel = (int) src_ptr[ i + (11*j)];
      if(temp_pixel>G){
        temp_pixel = G + ((temp_pixel-G)*(100-percent))/100;
      }else{
        temp_pixel = G - ((G-temp_pixel)*(100-percent))/100;
      }
      dst_ptr[i + (11*j)] = temp_pixel;
    }
  }  
}
void rotate_ccw_90deg( byte * src_ptr, byte * dst_ptr ){
  int i,j;
  for(i=0;i<11;i++){
    for(j=0;j<11;j++){
      dst_ptr[j + 11*(10-i)] = src_ptr[ i + (11*j)];
    }
  }
}
void setup() {
  Serial.begin(9600);
  while (!Serial);    // wait for the serial port to open

  Serial.println("Welcome to the Flightduino Test Code");

  // Setup the arrays for smiley faces in various orientations
  
  rotate_ccw_90deg(pattern,pattern_t90); // twist pattern 90 deg ccw and store in pattern_t90
  rotate_ccw_90deg(pattern_t90,pattern_t180); // twist pattern_t90 90 deg ccw and store in pattern_t180
  rotate_ccw_90deg(pattern_t180,pattern_t270); // twist pattern_t180 90 deg ccw and store in pattern_t270

  rotate_ccw_90deg(pattern_t45,pattern_t135); // twist pattern_t45 90 deg ccw and store in pattern_t135
  rotate_ccw_90deg(pattern_t135,pattern_t225); // twist pattern_t135 90 deg ccw and store in pattern_t225
  rotate_ccw_90deg(pattern_t225,pattern_t315); // twist pattern_t225 90 deg ccw and store in pattern_t315
  
  // Initialize the neurons
  hNN.begin();
  hNN.getNeuronsInfo( &neuronSize, &neuronsAvailable, &neuronsCommitted);
  Serial.print("Neuron size ="); Serial.println(neuronSize);
  Serial.print("Neurons available ="); Serial.println(neuronsAvailable);
  Serial.print("Neurons committed ="); Serial.println(neuronsCommitted);
  
  //Learn 8 patterns of smiley faces in various orientations
  Serial.print("\nLearning smiley face patterns...");
  hNN.learn(pattern,LEN, 360);
  hNN.learn(pattern_t45,LEN, 45);
  hNN.learn(pattern_t90,LEN, 90);
  hNN.learn(pattern_t135,LEN, 135);
  hNN.learn(pattern_t180,LEN, 180);
  hNN.learn(pattern_t225,LEN, 225);
  hNN.learn(pattern_t270,LEN, 270);
  hNN.learn(pattern_t315,LEN, 315);
  
 #ifdef DISPLAY_COMMITTED 
  // Display the content of the committed neurons
  Serial.print("\nDisplay the committed neurons, count="); Serial.print(neuronsCommitted);
  byte model[neuronSize];
  for (int i=1; i<=neuronsCommitted; i++)
  {  
      hNN.readNeuron(i, &ncr, model, &aif, &cat);
      Serial.print("\nneuron "); Serial.print(i); Serial.print("\tmodel=");
      for (int k=0; k<LEN; k++) { Serial.print(model[k]); Serial.print(", ");} 
      Serial.print("\tncr="); Serial.print(ncr);  
      Serial.print("\taif="); Serial.print(aif);     
      Serial.print("\tcat="); Serial.print(cat);
  }
 #endif
  int responseNbr;
 #ifdef SANITY_CHECK
  Serial.print("\n\nRecognizing a SMILEY: ");
  // Should be a perfect match!
  responseNbr=hNN.classify(pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 45 degree twisted SMILEY: ");
  responseNbr=hNN.classify(pattern_t45, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 90 degree twisted SMILEY: ");
  // Should be a perfect match!
  responseNbr=hNN.classify(pattern_t90, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 135 degree twisted SMILEY: ");
  responseNbr=hNN.classify(pattern_t135, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 180 degree twisted SMILEY: ");
  // Should be a perfect match!
  responseNbr=hNN.classify(pattern_t180, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 225 degree twisted SMILEY: ");
  responseNbr=hNN.classify(pattern_t225, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 270 degree twisted SMILEY: ");
  // Should be a perfect match!
  responseNbr=hNN.classify(pattern_t270, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 315 degree twisted SMILEY: ");
  responseNbr=hNN.classify(pattern_t315, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
      

  Serial.print("\n\nDone with sanity checking perfect data ");
#endif
// Where noise injected testing will go

  Serial.print("\n\nRecognizing a 0 percent faded SMILEY: ");
  fade(pattern, test_pattern, 0);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 2 percent faded SMILEY: ");
  fade(pattern, test_pattern, 2);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 4 percent faded SMILEY: ");
  fade(pattern, test_pattern, 4);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
      Serial.print("\n\nRecognizing a 6 percent faded SMILEY: ");
  fade(pattern, test_pattern, 6);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 8 percent faded SMILEY: ");
  fade(pattern, test_pattern, 8);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 9 percent faded SMILEY: ");
  fade(pattern, test_pattern, 9);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }          
  Serial.print("\n\nRecognizing a 10 percent faded SMILEY: ");
  fade(pattern, test_pattern, 10);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
            
  Serial.print("\n\n TEST 45 Degree CCW twist SMILEY ");
  Serial.print("\n\nRecognizing a 0 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 0);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 2 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 2);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 4 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 4);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
      Serial.print("\n\nRecognizing a 6 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 6);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 8 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 8);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 10 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 10);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 12 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 12);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 14 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 14);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
  Serial.print("\n\nRecognizing a 16 percent faded SMILEY: ");
  fade(pattern_t45, test_pattern, 16);
  responseNbr=hNN.classify(test_pattern, LEN, K, dists, cats, nids);
  for (int i=0; i<responseNbr; i++)
  {
      Serial.print("\nFiring neuron "); Serial.print(nids[i]);
      Serial.print(", Category="); Serial.print(cats[i]);
      Serial.print(", at Distance="); Serial.print(dists[i]);
  }
}

void loop()
{
#ifdef SERIAL_AVAIL  
  if (Serial.available() == 3) 
  {
      VAL = Serial.read() - 48;
      VAL = VAL *10 + Serial.read() - 48;
      Serial.read(); // to read the newline
      for (int i=0; i<LEN; i++) pattern[i]=VAL;     
      Serial.print("\npattern=");
      for (int i=0; i<LEN; i++) { Serial.print(pattern[i]); Serial.print(", ");}
    
      int responseNbr=hNN.classify(pattern, LEN, K, dists, cats, nids);
      for (int i=0; i<responseNbr; i++)
      {
          Serial.print("\nFiring neuron "); Serial.print(nids[i]);
          Serial.print(", Category="); Serial.print(cats[i]);
          Serial.print(", at Distance="); Serial.print(dists[i]);
      }  
      Serial.print("\n\nEdit a value between [10 and 30] as the amplitude of a new pattern + Enter");
   }
#endif   
 }

Schematics

Arduino Schematic
to keep the project submission system happy that I have included a schematic :)

Comments

Similar projects you might like

Rocky Rover: Robotic Vision System PixyCam & Arduino 101

Project tutorial by Ron Dagdag

  • 18,802 views
  • 7 comments
  • 125 respects

Arduino 101 Connects with Raspberry Pi Zero W

Project tutorial by Alexis Santiago Allende

  • 9,930 views
  • 0 comments
  • 18 respects

Small Segway with Arduino 101

Project tutorial by 3 developers

  • 7,376 views
  • 0 comments
  • 22 respects

SMS alerts for arduino 101 BLE

Project tutorial by Alexis Santiago Allende

  • 2,629 views
  • 0 comments
  • 10 respects

Motion Lamp with Arduino 101

Project tutorial by Team Programarfacil

  • 1,805 views
  • 0 comments
  • 3 respects

Smart Garbage Monitoring System Using Arduino 101

Project tutorial by Technovation

  • 35,581 views
  • 13 comments
  • 52 respects
Add projectSign up / Login