2018
February Thursday 22

Bookmark and Share

Related Articles...

MILWAUKEE WI Arduino Meet Up Make Space

WANTED: CORE TEAM MEMBER TO HELP START NON-PROFIT GROUP.

WANTED: Angle Investor Start-Up Funding

Large Industrial Zoned Arduino Make Space Acquired!

Email :

COASMailBox @ gmail.com

MILWAUKEE WI Raspberry Pi Meet Up Make Space

WANTED: CORE TEAM MEMBER TO HELP START NON-PROFIT GROUP.

WANTED: Angle Investor Start-Up Funding

Large Industrial Zoned Raspberry Pi Make Space Acquired!

Email :

COASMailBox @ gmail.com

MILWAUKEE WI Internet of Things (IoT) Meet Up Make Space

WANTED: CORE TEAM MEMBER TO HELP START NON-PROFIT GROUP.

WANTED: Angle Investor Start-Up Funding

Large Industrial Zoned Make Space Acquired!

Full Advanced Fabrication Facility, machine Shop, Welding, Electronics Lab Equipment Acquired!

Email :

COASMailBox @ gmail.com

MILWAUKEE WI Machine Repair, & Installation  - Tier 1 Business Support

Machine Technician Mechanic 20+ Years  Personal Experienced In Industrial Factory Machine Servicing, Rebuilding, Installation And Repair - Plus A 35+ Years Experienced Computer Engineer Service Technician Team Ready For Your Outsourced Market Advantage Needs!

Hartung Industrial - Member - CGI Science & Technology Group

Email :

COASMailBox @ gmail.com

2018 REVIEW

 

Arduino Faster DigitalRead(), DigitalWrite()

ARDUINO DEEP DIVE - ADVANCED PROFESSIONAL PROGRAMMING

2018 JAN | by Gene Casanova

Senior Systems/Network/Internet/Robotics Engineer


Using Lower Level Commands, To Greatly Increase Arduino I/O Speeds

There are three banks of pins on the Atmega328P and 168 microcontrollers, identified as "B", "C", and "D".

Each bank of pins has three 8-bit registers, used to control the bank:

  1. DDR register, defines data-direction; 0 = INPUT, 1 = OUTPUT.
  2. PIN register, used to read the digital-value of the pin.
  3. PORT register, has two functions:
    • If DDR is 0 (OUTPUT), then sets pin LOW; If  1m then sets pin HIGH.
    • If DDR is 1 (HIGH), then turns on the internal pull-up resistor on pin.

Each pin is 1-bit on the controlling registers.

The list of pins and corresponding registers:

B0 = digital pin 8
B1 = digital pin 9
B2 = digital pin 10
B3 = digital pin 11
B4 = digital pin 12
B5 = digital pin 13
B6 is mapped to the crystal, do not use.
B7 is mapped to the crystal, do not use.
C0 = analog pin 0
C1 = analog pin 1
C2 = analog pin 2
C3 = analog pin 3
C4 = analog pin 4
C5 = analog pin 5
C6 = analog pin 6, available only on Arduino MINI.
C7 = analog pin 7, available only on Arduino MINI.
D0 = digital pin 0, used for serial communication, save it's state.
D1 = digital pin 1, used for serial communication, save it's state.
D2 = digital pin 2
D3 = digital pin 3
D4 = digital pin 4
D5 = digital pin 5
D6 = digital pin 6
D7 = digital pin 7


Arduino, Blink A LED

Program an Arduino to blink a LED for the purpose of learning the process of developing source code, is the common starting point. The following examples will be based on using an 'Arduino UNO' class development systemboard. Notice the 'Arduino UNO' is an open-source development systemboard for the 'Atmega328P' microcontroller.

Also beware, the manufacturer of the 'Atmega328P' microcontroller IC chip, offers it in several different physical IC chip forms; "DIP", and surface-mount.  The same source-code is used for all forms of the 'Atmega328P' microcontroller.  The integrated circuit inside each of the different IC chips, is the same.

Example Arduino UNO Blink LED Source Code

/* Arduino
* Example Source Code to Blink A LED
* By Gene Casanova
* © 2017 | Open-Source
* This software must remain open-source and this copyright notice stay in place with all copies.
* 
* FUNCTION:
*  Set B5 (Digital Pin 13) to OUTPUT mode
*  by changing the DDRB register;
*  instead of using the pinMode() function.
*/
void setup()
{
DDRB = B00100000;
} /* Turn LED Connected to I/O Pin 13, ON/OFF, * by changing the PORTB register; * instead of using the digitalWrite() function.
*/ void loop() {
PORTB = B00100000; // LED ON; Binary Number; bit 5 set to 1 (HIGH).
delay(1000); // (delay() used for purpose of making this source-code easier to understand).
PORTB = B00000000; // LED OFF; Binary Number; bit 5 set to 0 (LOW).
delay(1000); // (delay() used for purpose of making this source-code easier to understand).
}

PORTB = B00100000;

The "B" before the binary number, indicates to the compiler, to interpret the number as a binary number.

The bits are numbered 0 to 7, the right most bit is the zero bit.

The source code, will also work with decimal numbers, in place of binary numbers.

Example Using Decimal Values

/* Arduino
* Example Source Code to Blink A LED
* By Gene Casanova
* © 2017 | Open-Source
* This software must remain open-source and this copyright notice stay in place with all copies.
* 
* FUNCTION:
*  Set B5 (Digital Pin 13) to OUTPUT mode
*  by changing the DDRB register;
*  instead of using the pinMode() function.
*/
void setup()
{
DDRB = 32;
} /* Turn LED Connected to I/O Pin 13, ON/OFF, * by changing the PORTB register; * instead of using the digitalWrite() function.
*/ void loop() {
PORTB = 32; // LED ON. Decimal value.
delay(1000); // (delay() used for purpose of making this source-code easier to understand).
PORTB = 0; // LED OFF. Decimal value.
delay(1000); // (delay() used for purpose of making this source-code easier to understand).
}

Example Using Variables

/* Arduino
* Example Source Code to Blink A LED
* By Gene Casanova
* © 2017 | Open-Source
* This software must remain open-source and this copyright notice stay in place with all copies.
* 
* FUNCTION:
*  Set B5 (Digital Pin 13) to OUTPUT mode
*  by changing the DDRB register;
*  instead of using the pinMode() function.
*/
int on = B00100000;
int off = B00000000; void setup()
{
DDRB = on;
} /* Turn LED Connected to I/O Pin 13, ON/OFF, * by changing the PORTB register; * instead of using the digitalWrite() function.
*/ void loop() {
PORTB = on; // LED ON; Using the variable 'on'.
delay(1000); // (delay() used for purpose of making this source-code easier to understand).
PORTB = off; // LED OFF; Using the variable 'off'.
delay(1000); // (delay() used for purpose of making this source-code easier to understand).
}

NOTICE:

Bits 6 and 7 are mapped to the onboard crystal.  Do not use these bits.


Use Pin Bank D, A Switch, And A LED

Bank D controls pins 0 - 7.  Notice, pins 0 and 1 are used for serial communication.  Some Arduino users preserve the values of bits 0 and 1 in the DDRD and PORTD registers.  This requires the use of logical 'AND' and 'OR' commands.

Each register is 8-bits, numbered 0 to 7, from right to left.  Bit 0 is 2^0, bit 1 is 2^1, etc..

A logical 'OR' compares two bytes, bit for bit, and the result is 1 if either or the bytes is 1; if not, the result is 0.

The vertical line (|) is the symbol for a logical 'OR' command.

Here is a logic "truth table" for a logical 'OR':

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

Example:

11001100 OR 00111100 = 11111100

A logical 'AND' compares two bytes, bit for bit, and the result is 1 only if both bits are 1.

The ampersand (&) is the symbol for a logical 'AND'.

Here is a logic "truth table" for a logical 'AND':

0 | 0 = 0
0 | 1 = 0
1 | 0 = 0
1 | 1 = 1

Example:

11001100 OR 00111100 = 00001100

To preserve a bit, OR it against 0, or, AND it against 1.

Follow along with the documentation in the program to see how this works.

Build the circuit with:

1) Arduino UNO
1) Breadboard
1) LED
1) Resistor, 220-560 Ohm
1) Momentary Pushbutton Switch
4) Breadboard jumper leads (wires)

Example Source Code

void setup()
{
  // Set pin 2 to INPUT and pin 7 to OUTPUT
  // while maintaining the STATE of pins 0 and 1.
  DDRD = DDRD | B10000000;

  // The "|" vertical line means logic 'OR'.
  // bit 7 is HIGH.
  // bits 0 and 1 are preserved.
  DDRD = DDRD & B10000011;

  // Do a logic 'AND' to get status of all bits.

  // A logical OR against zero or a logical AND against one
  // will not change the status of a bit.

  // This preserved the status of bits 7, 1, and 0.
  // Since bit 2 was ANDed against 0 we know that it is now clear.
  // The DDRD register is now where we want it.
 
  // Now we need to get the PORTD register set the way we want it.

  PORTD = PORTD & B00000011;

  // Bits 0 and 1 are preserved, all others are off.

  PORTD = PORTD | B00000100;

  // Bits 7 is off, the initial state of the LED.
  // Bit 2 is on, because pin 2 is an input turning it's bit
  // on in PORTD turns on the internal pull-up resistor.
}

/**********************************************
 * loop() function
 **********************************************/
void loop()
{
  // Read the PIND register.

  int button = PIND;

  // you now have the values of all eight pins in the PIND register
  // contained in a variable. The only pin we care about is pin 2.
  // So we do a logical AND on the button variable to isolate the
  // bit we want.
       
  button = button & B00000100;

  // Because of the internal pull-up resistor the pin will be high
  // if the button is not pressed, and low if it is.
  // So button will return either 2^2 (4) or zero if it is pressed.

  PORTD = PORTD & B00000111;

  // Turn LED off, and preserve bits 0 - 2.
 
  if(button == 0) 
  {
    PORTD = PORTD | B10000000;
  // turn LED on, and preserve bits 0 - 2.
  }
}

The digitalWrite() command will slow a program down in a loop.  The pinMode() command is normally used only in the setup() function, and ran once.  The program above will run just as well if a more standard setup() function was used, like this:

setup() {
   pinMode(7, OUTPUT);
   pinMode(2, INPUT_PULLUP;
}

Controlling registers directly, eliminates a lot of extra source-code, and, enables reading and writing all pins in a bank, with one command.


Arduino Speed Experiment Demonstration

Build the experiment circuit using the following:

Example Source Code

/*
 * 2018 JAN
 * 
 * Arduino Fast Counter
 *
 * A fast binary counter works by controlling the registers,
 * rather than using the digitalWrite() function.
 * 
 * Professional Grade Programming Demonstration.
 * Notice: Parallel Processing is occurring here.
*/

void setup() {
   DDRB = B00111111; // Pins 8-13 set to OUTPUT mode.
}

void loop() {
	
	for(int i=0;i<64;i++)
	{
		PORTB = i;
		delay(500); // delay() used here to keep code understanding simple.
	}
}

Upload this program to the Arduino and allow it to run for 5 minutes.  Notice the speed does not change in the blinking LEDs.

Also notice, when all LEDs are On, and they all go out in an instant, and at the same time.

Compare The above to this typical source code method:

setup() {
   pinMode(7, OUTPUT);
   pinMode(2, INPUT_PULLUP;
}

The first time all the LEDs go off, notice there is a slight delay, and see them go off in sequence.  The longer this program runs, the slower it gets.


Arduinos Maximum I/O Pins Available

When needing more Digital I/O pins, the Analog I/O pins can be used as Digital I/O pins.

Load the fast counter program above, into your Arduino IDE application.

In the setup() function, change "DDRB" to "DDRC".

In the loop() function, change "PORTB" to "PORTC".

Next, move the jumper lead wires from Digital I/O pins 8 - 13, to Analog I/O pins 0 - 5.

Upload the program to an Arduino UNO, and notice you now have six additional Digital I/O pins.


Use The Technology Wisely & Keep It Simple

- Cheers!

Gene Casanova


Cyber Security Since 1979 - Consulting Available By Subscription

CGI Computer Wares | EST 1979

Send E-MailCONTACT: [click]@CGIComputerWares.com