The Arduino Handbook - Learn Microcontrollers For Embedded Systems
The Arduino Handbook - Learn Microcontrollers For Embedded Systems
Home automation.
Automation in agriculture.
Electronic prototyping.
Prerequisites
Although it would be helpful, you don't need prior
programming knowledge to use this handbook. You
Forumfrom Donate
will learn the basics of Arduino programming
scratch. This cantoalso
Learn code serve as your introduction
— free 3,000-hour curriculum to
programming.
Table of Contents:
Prerequisites
Chapter 1: Getting
Started with
Arduino
The Arduino development and design process
comprises both hardware and software. So knowing
how they work together is important for building the
right foundation for your journey.
the Uno R3 board, but you can follow along with either
of them. The R4 board comes in two variants —
Arduino Uno R4 WiFi and Arduino Uno R4 Minima —
with cool additional features that you can read about
here.
Components of the
Arduino Uno R3 Board
There are many types of Arduino boards like Arduino
Nano, Arduino Uno, Arduino Mega, Arduino Leonardo,
and so on.
A power port.
USB connector.
Microcontroller (ATmega328).
Analog pins.
Digital pins.
Reset button.
TX and RX indicators.
Arduino Uno R3 board (https://store.arduino.cc/products/arduino-
Forum Donate
uno-rev3)
Learn to code — free 3,000-hour curriculum
I'll use the ZIP file option for Windows. If you decide
to download an installer instead, then you can follow
the installation steps after clicking the installation file.
Step #2 – Unzip the Downloaded Forum Donate
After unzipping the file, you should see files like these:
https://docs.arduino.cc/software/ide-v2/tutorials/getting-started-
ide-v2
What Is an Arduino
Learn to code — free 3,000-hour curriculum
Sketch?
We mentioned the term “sketch” a couple of times in
the last section, but what is it? A sketch is a program
written with the Arduino programming language. It’s
another way of referring to a code file written for
Arduino projects.
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
}
Chapter 2: Basics of
Learn to code — free 3,000-hour curriculum
Arduino
Programming
Before we dive into creating our own sketches and
tinkering, you have to understand the logic that make
these boards work as expected. To do that, you’ll have
to know how to code using the Arduino programming
language.
in Arduino
Variables and data types are used in most
programming languages to store and manipulate data.
You can think of variables as containers or storage
units. Data types, like the name implies, are the type of
data stored in variables.
int redLED = 6;
Forum Donate
In the code above, we created an integer variable
Learn to code — free 3,000-hour curriculum
called redLED with a value of 6.
Here's an example:
The byte data type isn't the only data type that can be
unsigned. You can also use the unsigned int ,
unsigned long , and unsigned char data types which
all have their respective positive integer ranges.
Operators in Arduino
Operators are symbols or characters that can be used
to perform certain operations on operands. An
operand is simply any value(s) an operator acts on.
Arithmetic Operators
Arithmetic operators are used to perform
mathematical operations like addition, subtraction,
division, multiplication, and so on. Here are some
arithmetic operators you should know:
Addition(+) Operator Forum Donate
The addition operator,
Learn to code —denoted by the
free 3,000-hour + symbol, adds
curriculum
int a = 5;
int b = 10;
Serial.print(c);
// 15
Subtraction(-) Operator
The subtraction operator subtracts the value of one
operand from another operand. It is denoted by the -
symbol:
int a = 5;
int b = 10;
Serial.print(c);
// 5
Multiplication (*) OperatorForum Donate
int a = 5;
int b = 10;
Serial.print(c);
// 50
Division(/) Operator
The division operator divides one operand by another:
int a = 5;
int b = 10;
Serial.print(c);
// 2
int a = 5;
int b = 10;
Serial.print(c);
// 0
int num = 5;
num++;
Serial.print(num);
// 6
Serial.print(num);
// 4
Assignment Operators
Assignment operators are mainly used to assign
values to variables. You can also use them to update
the value of variables.
int age = 1;
int x = 5;
x += 5;
Serial.print(x)
// 10
x += 5;
Forum Donate
The line of code above
Learn to code —is the
free same as
3,000-hour this:
curriculum
x = x + 5;
int a = 10;
a -= 5; // Equivalent to a = a - 5 (a becomes 5)
int b = 10;
b *= 5; // Equivalent to b = b * 5 (b becomes 50)
int c = 10;
c /= 5; // Equivalent to c = c / 5 (c becomes 2)
int d = 10;
d %= 5; // Equivalent to d = d % 3 (d becomes 0)
Comparison Operators
You can use comparison operators to compare two
values/operands. Comparison operators return either
true (1) or false (0) depending on the Forum
relationshipDonate
between operands.
Learn to code — free 3,000-hour curriculum
int x = 10;
int y = 5;
Serial.print(x == y)
// returns 0
Here's an example:
int x = 10;
int y = 5;
Serial.print(x != y)
// returns 1
int x = 10;
int y = 5;
Serial.print(x > y)
// returns 1
Forum Donate
Learn to code — free 3,000-hour curriculum
Less Than (<) Operator
The less than ( < ) operator checks if the operand on
the left is less than the operand on the left. If the left
operand is smaller, it returns 1. If the left operand is
greater, it returns 0.
int x = 10;
int y = 5;
Serial.print(x < y)
// returns 0
Serial.print(x >= y)
// returns 1
int x = 10;
int y = 5;
Serial.print(x <= y)
// returns 0
Logical Operators
Logical operators are used in most programming
languages to evaluate and determine the relationship
between variables.
Here are the three logical operators youForum
should know
Donate
for ArduinoLearn
programming:
to code — free 3,000-hour curriculum
int x = 10;
int x = 10;
Here's an example:
int x = 10;
if Statement
The if statement is used to execute code if a
condition is true . Here's what the syntax looks like:
if (condition) {
// code to be executed if condition is true
}
// x is less than 10
else Statement
The else statement is used to execute code if a
condition is false .
int score = 20;
Forum Donate
if (score Learn
> 50 to
) code
{ — free 3,000-hour curriculum
Serial.print("You passed the exam!");
} else {
Serial.print("You have to rewrite the exam!");
}
else if Statement
You can use the else if statement to define multiple
conditions to be checked. Here's the syntax:
if (condition1) {
// code to be executed if condition1 is true
} else if (condition2){
// code to be executed if condition2 is true
} else {
// code to be executed if condition1 and con
}
Forum Donate
Learn
In the syntax to code
above, — free are
there 3,000-hour curriculum (you can
two conditions
create more than two conditions). If condition1 is
true , then code in the curly bracket for condition1
will be executed.
switch-case Statement
In the last section, we saw how to create multiple
conditions using else if statements. Your code
Forum
might become hard to read if you have many Donate
conditions. Learn
We can clean
to code it3,000-hour
— free up and make the code
curriculum
switch (expression) {
case 1:
// Code to be executed if expression equals
break;
case 2:
// Code to be executed if expression equals
break;
case 3:
// Code to be executed if expression equals
break;
default:
// Code to be executed if expression doesn't
break;
}
Here's an example:
int day = 2;
switch (day) {
case 1:
Serial.print("Monday");
break;
case 2:
Serial.print("Tuesday");
break;
case 3:
Serial.print("Wednesday");
break;
case 4:
Serial.print("Thursday");
break;
case 5:
Serial.print("Friday");
break;
case 6:
Serial.print("Saturday");
break;
case 7:
Serial.print("Sunday");
break;
default:
Serial.print("Number out of range");
Forum Donate
}
Learn to code — free 3,000-hour curriculum
// Tuesday
Loops in Arduino
You can use loops to execute code repeatedly until a
certain condition is met. You can also use loops to
iterate over a collection of data and execute code on
all elements of the collection.
for loop
You can use the for loop to iterate through a
collection or execute code until a certain condition is
met. It is commonly used when you know the number
of times the loop is supposed to run.
while loop
The while loop works just like the for Forum
loop — it Donate
executes code
Learnas
tolong asfree
code — the given condition
3,000-hour curriculum is true .
But its often used when the number of times the loop
is supposed to run is unknown.
while (condition) {
// Code to be executed
}
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
Forum Donate
// 10
Learn to code — free 3,000-hour curriculum
do-while Loop
The do-while loop is just like the while loop, but it
executes its code block first before checking the
validity of the condition given. That is, at the beginning
of the loop, the code in curly brackets will run first
even if the condition is false . After that, it starts
checking if the condition is true or false , just like a
normal loop.
do {
// code block to be executed
}
while (condition);
int i = 0;
do {
Forum Donate
Serial.println(i);
i++; Learn to code — free 3,000-hour curriculum
} while ( i < 11);
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10
Arrays in Arduino
You can use arrays in Arduino to store multiple
variables of the same data type in a single variable.
Each element stored in an array can be accessed using
its index number.
Array Declaration
Declaring an array simply means to create one. You
can do that in Arduino using the syntax below:
dataType arrayName[arraySize]
Forum Donate
In the syntax above:
Learn to code — free 3,000-hour curriculum
int ages[4];
Array Initialization
To initialize an array means to assign values to the
array. In the last section, we created an array called
ages . Now, let's assign some elements to it:
Forum Donate
int ages[4] = {2, 4, 6, 8};
Learn to code — free 3,000-hour curriculum
You can see from the example above that there are
only four elements in the array — 2, 4, 6, 8. Assigning a
fifth element would throw an error because we
specified that the array can only have for integer
elements: int ages[4]; .
Serial.print(ages[0]);
// 2
Functions in Arduino
In the last chapter, we discussed some built-in
functions in Arduino that can be used to carry out a
variety of tasks related to Arduino hardware and
software components. All we did was write the
function name and pass in parameters where
necessary and we got the desired outcome.
dataType functionName(optionalParameters) {
// body of the function
}
Forum
So from the syntax above, dataType is the data typeDonate
the functionLearn
returns.
to codeIt
— can be int , curriculum
free 3,000-hour String , and so on.
A function that has no return statement uses the
void type as its data type.
The body of the function is where all the logic goes to.
What the function does when it is invoked is written in
the body.
the void
LearnType
to code — free 3,000-hour curriculum
void functionName(optionalParameters) {
// code logic
}
Here's an example:
Forum Donate
Learn to code — free 3,000-hour curriculum
// function declaration
void printName(String userName) {
Serial.println("Hello " + userName);
}
void setup() {
Serial.begin(9600);
}
void loop() {
printName("Ihechikara"); // function call
delay(1000);
}
// function declaration
int addNums(int a, int b) {
int result = a + b;
return result;
}
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(addNums(2, 10)); // function call
delay(1000);
}
Forum
In the code above, we declared a function with the Donate
int type: int
LearnaddNums(int b) {...} . This
a, intcurriculum
to code — free 3,000-hour
Serial.println(addNums(2, 10));
int result = a + b;
Serial.println(result);
return result;
void setup() {
// put your setup code here, to run once:
void loop() {
// put your main code here, to run repeatedly:
Syntax
pinMode(pin, mode)
Forum Donate
Learn to code — free 3,000-hour curriculum
digitalRead() Function in
Arduino
You can use the digitalRead() function to read the
state of digital pins. It returns either 0 ( LOW ) or 1
( HIGH ).
Syntax
digitalRead(pin)
digitalWrite() Function in
Arduino
The digitalWrite() function assigns orForum
writes values
Donate
(either HIGHLearn
or toLOW ) to
code digital
— free pins. curriculum
3,000-hour
Syntax
digitalWrite(pin, value)
Syntax
analogRead(pin)
Arduino
This function writes or assigns an analog value to a
pin.
Syntax
analogWrite(pin, value)
Serial Functions in
Arduino
Serial communication enables an Arduino board to
communicate with the computer and other devices
using the built-in serial monitor. Here are some of the
commonly used functions:
Serial.begin()
The Serial.begin() function initializesForum
serial Donate
communication.
Learn toItcode
is the first
— free function
3,000-hour you use when
curriculum
Serial.begin(baudRate)
Serial.print() and
Serial.println()
You can use the print() and println() functions to
print data to the serial monitor.
print(val)
println(val)
delay(ms)
Chapter 3: How to
Use Digital Pins in
Arduino
Digital pins are used to send and receive digital signals
in two states — HIGH and LOW . The digital pins on a
Arduino board can be configured as either input or
output pins.
Forum
These states can also be represented using numbersDonate
(1 for HIGH Learn
and to
0 code
for — free),3,000-hour
LOW or in volts (V) (5V for HIGH
curriculum
Pins
When a digital pin is configured as an INPUT pin, it
serves as a point for receiving information from
components. This way you get data from sensors,
electronic components, and so on.
Arduino Uno.
Breadboard.
Pushbutton.
Jumper wires.
void setup(){
pinMode(pushBtn, INPUT_PULLUP);
Serial.begin(9600);
}
void loop(){
push_btn_state = digitalRead(pushBtn);
Serial.println(push_btn_state);
delay(1000);
}
int pushBtn = 7;
int push_btn_state;
function:
pinMode(pushBtn, INPUT_PULLUP);
push_btn_state = digitalRead(pushBtn);
Forum
After that, we printed the value being read from pinDonate
7
to the serialLearn
monitor
to codeusing
— free 3,000-hour curriculum
Serial.println(push_btn_state); .
Arduino Uno.
Red LED. Forum Donate
Jumper wires.
Breadboard.
int RedLED = 8;
void setup(){
pinMode(RedLED, OUTPUT);
}
void loop(){
digitalWrite(RedLED, HIGH);
delay(1000);
digitalWrite(RedLED, LOW);
delay(1000);
Forum Donate
}
Learn to code — free 3,000-hour curriculum
digitalWrite(RedLED, HIGH);
delay(1000);
digitalWrite(RedLED, LOW);
delay(1000);
Arduino Uno.
Red LED.
1k Ohm resistor.
Pushbutton.
Jumper wires.
Breadboard.
int pushBtn = 7;
int push_btn_state;
int RedLED = 8;
void setup(){
pinMode(pushBtn, INPUT_PULLUP);
pinMode(RedLED, OUTPUT);
}
void loop(){
push_btn_state = digitalRead(pushBtn);
if (push_btn_state == 1) {
digitalWrite(RedLED, HIGH);
} else {
digitalWrite(RedLED, LOW);
}
}
Chapter 4: How to
Use Analog Pins in
Arduino
Analog pins can be used to receive and send voltage
values from/to different sensors and components.
Unlike digital signals that fall within two states of 0
( LOW ) and 1 ( HIGH ), analog values have a wider range
of values from 0 to 1023.
The Uno board has six analog pins — A0, A1, A2, A3,
A4, and A5. These pins are INPUT pins by default.
Arduino Uno.
Yellow LED.
Potentiometer.
1k Ohm resistor.
Jumper wires. Forum Donate
Learn to code — free 3,000-hour curriculum
Breadboard.
Configuration diagram
void setup(){
pinMode(potentiometer, INPUT);
pinMode(yelowLED, OUTPUT);
}
void loop(){
pot_value = analogRead(potentiometer);
pot_in_PWM = pot_value * (255.0 / 1023.0);
Forum Donate
Learn to code — free
analogWrite(yelowLED, 3,000-hour curriculum
pot_in_PWM);
}
Chapter 5: How to
Use Sensors and
Actuators in
Arduino
Sensors and actuators play a crucial role in developing
projects using Arduino. They help microcontrollers get
information about changes in the physical
environment, and make decisions based on that
information.
actuators in a project.
There are other types of sensors that you can use with
Arduino, but we'll just focus on two: the LDR (light-
dependent resistor) and ultrasonic sensor.
ResistorLearn
(LDR) in3,000-hour
to code — free Arduino curriculum
Diagram of an LDR
Configuration diagram
void setup() {
pinMode(ldrPin, INPUT);
Serial.begin(9600);
}
void loop() {
ldrValue = analogRead(ldrPin);
Serial.println(ldrValue);
delay(1000);
Forum Donate
}
Learn to code — free 3,000-hour curriculum
ldrValue = analogRead(ldrPin);
Automated doors.
Security systems.
The sensor has four pins — VCC, Trig, Echo, and GND.
int trigPin = 9;
int echoPin = 10;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
delay(1000);
}
Forum Donate
In the code above, the trig pin denotes digital pin 9,
Learn to code — free 3,000-hour curriculum
and the echo pin denotes digital pin 10.
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
int redLED = 7;
void setup() {
pinMode(redLED, OUTPUT);
}
void loop() {
digitalWrite(redLED, HIGH);
delay(1000);
digitalWrite(redLED, LOW);
delay(1000);
}
The code above will make the LED blink once the code
has been uploaded.
Alarm systems.
Doorbells.
void setup() {
pinMode(buzzerPin, OUTPUT);
}
void loop() {
for (int i = 0; i < 8; i++) {
tone(buzzerPin, notes[i], noteDurations[i]);
delay(noteDurations[i] + 50);
noTone(buzzerPin);
}
delay(1000);
}
duration.
int redLED = 7;
void setup() {
pinMode(ldrPin, INPUT);
pinMode(redLED, OUTPUT);
Serial.begin(9600);
}
void loop() {
ldrValue = analogRead(ldrPin);
Serial.println(ldrValue);
delay(1000);
}
Chapter 6: How to
Use the Serial
Monitor in Arduino
The serial monitor is a useful tool for every Arduino
builder. You can use it for a variety of tasks like:
Serial.begin(baudRate)
void setup() {
Serial.begin(9600);
void loop() {
// put your main code here, to run repeatedly:
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("Hello");
delay(1000);
}
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Hi");
delay(1000);
}
available() Function
The Serial.available() function checks the number
of characters in the serial port. It is mostly use to run
code only when data is available in the serial monitor.
int userInput;
void setup(){
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
userInput = Serial.parseInt();
Serial.println(userInput);
}
readString() Function
You can use the readString() function to read
characters from the serial monitor. It returns a string
object so whatever values/characters you input in the
serial monitor will be seen as string values when using
the readString() function.
String userInput;
void setup(){
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
userInput = Serial.readString();
Serial.println(userInput);
}
Forum Donate
}
Learn to code — free 3,000-hour curriculum
parseInt() Function
The parseInt() function returns valid integer values
from incoming serial data. Non integer values will be
returned as 0.
int userInput;
void setup(){
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
userInput = Serial.parseInt();
Serial.println(userInput);
}
parseFloat() Function
The parseFloat() function returns valid floating
point numbers from incoming serial data.
float userInput;
Forum Donate
Learn to code — free 3,000-hour curriculum
void setup(){
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
userInput = Serial.parseFloat();
Serial.println(userInput);
}
int redLED = 6;
int blueLED = 5;
int yellowLED = 4;
String userInput;
void setup(){
pinMode(redLED, OUTPUT);
pinMode(blueLED, OUTPUT);
pinMode(yellowLED, OUTPUT);
Serial.begin(9600);
userInput = Serial.readString();
if (userInput == "red") {
digitalWrite(redLED, HIGH);
digitalWrite(blueLED, LOW);
digitalWrite(yellowLED, LOW);
}
if (userInput == "blue") {
digitalWrite(redLED, LOW);
digitalWrite(blueLED, HIGH);
digitalWrite(yellowLED, LOW);
}
if (userInput == "yellow") {
digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
digitalWrite(yellowLED, HIGH);
}
int redLED = 6;
int blueLED = 5;
int yellowLED = 4;
pinMode(redLED, OUTPUT);
pinMode(blueLED, OUTPUT);
pinMode(yellowLED, OUTPUT);
Serial.begin(9600);
if (Serial.available() > 0) {
...
}
userInput = Serial.readString();
Lastly, we used if statements to check Forum
which LED Donate
color value Learn
the user has
to code typed
— free in/sent
3,000-hour through the
curriculum
if (userInput == "red") {
digitalWrite(redLED, HIGH);
digitalWrite(blueLED, LOW);
digitalWrite(yellowLED, LOW);
}
if (userInput == "blue") {
digitalWrite(redLED, LOW);
digitalWrite(blueLED, HIGH);
digitalWrite(yellowLED, LOW);
}
if (userInput == "yellow") {
digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
digitalWrite(yellowLED, HIGH);
}
Use Displays in
Arduino
You can use display components in Arduino to
represent data visually in different formats like text,
images, and so on.
The first pin from the left is the GND pin, which
is the LCD's ground pin. It is connected to GND
on the Arduino board. In some LCD modules, it
may be written as VSS.
Example #1 – How to
Connect and Use an LCD
with Arduino
In the last section, we talked about the meaning of the
pins on an LCD. In this section, you'll see a practical
Forumand write
example on how to connect them in a circuit, Donate
code to display
Learndata on
to code the3,000-hour
— free LCD. curriculum
Arduino Uno.
16 x 2 LCD.
Potentiometer.
Jumper wires.
Resistors.
Breadboard.
#include <LiquidCrystal.h>
void setup() {
lcd.begin(16, 2);
lcd.print("freeCodeCamp!");
}
void loop() {
Example #2 – How to
Display User Input with
LCD in Arduino
In this example, we'll accept input from the user using
the serial monitor, and display the input along with a
welcome message on the LCD screen.
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
String userInput;
Forum Donate
void setup() {
Learn to code — free 3,000-hour curriculum
Serial.begin(9600);
lcd.begin(16, 2);
lcd.print("Input name");
lcd.setCursor(0, 1);
}
void loop() {
if (Serial.available() > 0) {
userInput = Serial.readString();
lcd.print("Welcome " + userInput);
}
}
Example #2 Alternative
An alternative way to print the message to the user is
by using the same line where the initial message was
Forum
displayed. We can clear whatever is written on the Donate
first row of Learn
the LCD and
to code display
— free a different
3,000-hour curriculumvalue.
Here's how:
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
String userInput;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.print("Input name");
}
void loop() {
if (Serial.available() > 0) {
lcd.clear();
userInput = Serial.readString();
lcd.print("Welcome " + userInput);
}
}
Example #3 – How to
Display Sensor Data with
LCD in Arduino
In this example, we'll display data from a sensor on the
LCD. We'll use the temperature sensor. The logic here
is to sense the temperature of a room and display the
varying values on the LCD.
Arduino Uno.
16 x 2 LCD.
Potentiometer.
Jumper wires.
Resistors.
Breadboard.
Here's the circuit diagram: Forum Donate
Learn to code — free 3,000-hour curriculum
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
void setup() {
pinMode(ldrPin, INPUT);
lcd.begin(16, 2);
}
Forum Donate
void loop() {
ldrValueLearn to code — free 3,000-hour curriculum
= analogRead(ldrPin);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LDR value:");
lcd.setCursor(0, 1);
lcd.print(ldrValue);
delay(1000);
}
ldrValue variable.
Conclusion
Congratulations! We've come to the end of this
handbook. You now have enough knowledge to take
on bigger projects.
Happy tinkering!
If you read this far, thank the author to show them you
care. Say Thanks
Our mission: to help people learn to code for free. We accomplish this by creating thousands of
videos, articles, and interactive coding lessons - all freely available to the public. We also have
thousands of freeCodeCamp study groups around the world.
Donations to freeCodeCamp go toward our education initiatives, and help pay for servers,
services, and staff.
Trending Guides
About Alumni Network Open Source Shop Support Sponsors Academic Honesty