Throw out your breadboard! Dr. Duino: An Arduino Shield for debugging and developing

preview_player
Показать описание
🤩 FREE Arduino Crash Course 👇👇

*Click Below to Read About This Topic on Our Website*

*Description:*

In the last couple of episodes we have talked about Arduino shields and breakout boards. In this video, we will review a specific Arduino shield that makes developing projects and debugging sketches on the Arduino extremely easy - it's called Dr. Duino.

An Arduino Shield for Arduino Shields

The Dr. Duino is an Arduino Shield. As would expect, it fits snuggly on top of the Arduino headers and has pin headers of it's own, which can easily accept a shield on top.

The first thing you notice about Dr. Duino is that it's built like a doughnut - it's got a giant hole in the middle! (FYI - It does not taste like said pastry…)

There are a couple reasons for this form factor, but foremost is that even after you stack another shield on top of Dr. Duino, you still have easy physical access to all its resources.

Dr. Duino Hardware Resources

What resources are we talking about? Dr. Duino has 4 momentary pushbuttons, 5 LEDs, 6 potentiometers, an RS232 connector, and a bunch of access points for 5 volts, 3.3 volts and ground, oh yeah, and a siren (piezo buzzer).

So how do you access these resources and why would you even care to? Both great questions!

The core feature that allows us to use all the hardware I just talked about are groups of three “jumper” pins that surround the board.

Almost every pin on the Arduino is associated with a set of these jumper pins. The middle pin is connected directly to the Arduino pin.

The pin on the left is connected to the pin header on top of the Dr. Duino. The pin on the right is connected to the one of the hardware resources on the Dr. Duino board.

With each set of these three jumper pins we get a plastic encased "jumper" - it fits snug on top 2 pins, and electrically connects them together.

For every Arduino pin that has associated Dr. Duino jumper pins we have 2 decisions:

1) We can route the Arduino pin to the shield above by connecting the center pin to the jumper pin on the left. This passes the Arduino pin directly up to the shield if you have one attached, bypassing the Dr. Duino.

2) Or, we can route the Arduino pin to the resource on the Dr. Duino shield, bypassing the shield above. Each pin has a different "resource" or piece of hardware that you can use.

Here is a quick mnemonic for remembering how to place the “jumper” on the “jumper pins” – Left goes Up (to the shield above), Right goes to Down (to the Dr. Duino).

Digital pins 5, 6, 10, 11, and 13 have LEDs attached. Digital Pins 7, 8, 9 and 12 have momentary pushbuttons attached. Analog pins A0 - A5 have potentiometers attached and digital pin 3 is attached to the piezo buzzer.

All these asset are extremely helpful.

For example, let's say I am prototyping with a motor shield. What I want is for every time I press a button, then a servo moves 180 degrees. Instead of having to bust out a breadboard and jumper wires, I simply move a jumper on the Dr. Duino and I now have a preinstalled button. As long as the shield is not using that pin for anything, it's fair game to route that pin to the Dr. Duino.

Or, maybe I want to turn a potentiometer to get the servo to move. Once again - scrap the breadboard - just move a jumper on one of the analog pins and you have a built in potentiometer - in fact, every analog pin has its own dedicated potentiometer! Trying to put 6 potentiometers on a breadboard and run jumpers is a major pain - having these built right in and so compact is great.

Potentiometers are great for simulating sensor inputs too. Say you are developing a project that lights up LEDs based on inputs from a pressure sensor - but you don't have the sensor yet. No worries - just use the potentiometer built in to the Dr. Duino to simulate the input from the pressure sensor.

Another great resource is the piezo buzzer. Most of us get used to using the serial window to debug our sketches. For example - we use the Serial .print() function to send a value to the serial monitor window when some threshold is met.

Read more at...

*About Us:*
This Arduino tutorial was created by Open Source Hardware Group. We are an education company who seek to help people learn about electronics and programming through the ubiquitous Arduino development board.

Have an awesome day!
Рекомендации по теме
Комментарии
Автор

I think for beginners the breadboard is a great tool for learning circuits. This shield takes away that learning process!

fpvrcstuff
Автор

Dr. Duino + Ruggeduino = pure awesomeness and protection

moniiiiiiiiii
Автор

Dr. Duino + Ruggeduino should be available in Arduino kits online but they sadly not cheap for everyone

qrjftvx
Автор

i put my breadboard in the bin, getting the soldering iron out, going to solder resistors to leds, leads to all pins going to 6 amp connector blocks, all components going to 6 amp blocks and a breadboard made of connector blocks

gimmieliberty
Автор

how many MPU6050 sensors can be connect to uno? Can those sensors be able to send their respective data?
Typically Arduino UNO

Life--and--Living
Автор

Ok, Dr.duino is good, but why throw out our breadboard?

mattroh
Автор

the best shield! this is what im lf! problem solved :v

CaraAmar
Автор

Gotta say thanks, suddenly my ESP8266 programmers board which has no directions in English that I have found looks a lot like your dr duino perhaps the comparison can make them useful.

JerryEricsson
Автор

PLEASE DEBUG THIS UNO OR MEGA CODE: /* Mini CNC Plotter code */

#include <Servo.h>
#include <AFMotor.h>

#define LINE_BUFFER_LENGTH 512

char STEP = MICROSTEP ;

// Servo position for Up and Down
const int penZUp = 95;
const int penZDown = 83;

// Servo on PWM pin 10
const int penServoPin =10 ;

// Should be right for DVD steppers, but is not too important here
const int stepsPerRevolution = 48;

// create servo object to control a servo
Servo penServo;

// Initialize steppers for X- and Y-axis using this Arduino pins for the L293D H-bridge
AF_Stepper myStepperY(stepsPerRevolution, 1);
AF_Stepper myStepperX(stepsPerRevolution, 2);

/* Structures, global variables */
struct point {
float x;
float y;
float z;
};

// Current position of plothead
struct point actuatorPos;

// Drawing settings, should be OK
float StepInc = 1;
int StepDelay = 0;
int LineDelay =0;
int penDelay = 50;

// Motor steps to go 1 millimeter.
// Use test sketch to go 100 steps. Measure the length of line.
// Calculate steps per mm. Enter here.
float StepsPerMillimeterX = 100.0;
float StepsPerMillimeterY = 100.0;

// Drawing robot limits, in mm
// OK to start with. Could go up to 50 mm if calibrated well.
float Xmin = 0;
float Xmax = 40;
float Ymin = 0;
float Ymax = 40;
float Zmin = 0;
float Zmax = 1;

float Xpos = Xmin;
float Ypos = Ymin;
float Zpos = Zmax;

// Set to true to get debug output.
boolean verbose = false;

// Needs to interpret
// G1 for moving
// G4 P300 (wait 150ms)
// M300 S30 (pen down)
// M300 S50 (pen up)
// Discard anything with a (
// Discard any other command!


* void setup() - Initialisations

void setup() {
// Setup

Serial.begin( 9600 );

penServo.attach(penServoPin);
penServo.write(penZUp);
delay(100);

// Decrease if necessary
myStepperX.setSpeed(600);

myStepperY.setSpeed(600);


// Set & move to initial default position
// TBD

// Notifications!!!
Serial.println("Mini CNC Plotter alive and kicking!");
Serial.print("X range is from ");
Serial.print(Xmin);
Serial.print(" to ");
Serial.print(Xmax);
Serial.println(" mm.");
Serial.print("Y range is from ");
Serial.print(Ymin);
Serial.print(" to ");
Serial.print(Ymax);
Serial.println(" mm.");
}


* void loop() - Main loop

void loop()
{

delay(100);
char line[ LINE_BUFFER_LENGTH ];
char c;
int lineIndex;
bool lineIsComment, lineSemiColon;

lineIndex = 0;
lineSemiColon = false;
lineIsComment = false;

while (1) {

// Serial reception - Mostly from Grbl, added semicolon support
while ( Serial.available()>0 ) {
c = Serial.read();
if (( c == '\n') || (c == '\r') ) { // End of line reached
if ( lineIndex > 0 ) { // Line is complete. Then execute!
line[ lineIndex ] = '\0'; // Terminate string
if (verbose) {
Serial.print( "Received : ");
Serial.println( line );
}
processIncomingLine( line, lineIndex );
lineIndex = 0;
}
else {
// Empty or comment line. Skip block.
}
lineIsComment = false;
lineSemiColon = false;
Serial.println("ok");
}
else {
if ( (lineIsComment) || (lineSemiColon) ) { // Throw away all comment characters
if ( c == ')' ) lineIsComment = false; // End of comment. Resume line.
}
else {
if ( c <= ' ' ) { // Throw away whitepace and control characters
}
else if ( c == '/' ) { // Block delete not supported. Ignore character.
}
else if ( c == '(' ) { // Enable comments flag and ignore all characters until ')' or EOL.
lineIsComment = true;
}
else if ( c == ';' ) {
lineSemiColon = true;
}
else if ( lineIndex >= LINE_BUFFER_LENGTH-1 ) {
Serial.println( "ERROR - lineBuffer overflow" );
lineIsComment = false;
lineSemiColon = false;
}
else if ( c >= 'a' && c <= 'z' ) { // Upcase lowercase
line[ lineIndex++ ] = c-'a'+'A';
}
else {
line[ lineIndex++ ] = c;
}
}
}
}
}
}

void processIncomingLine( char* line, int charNB ) {
int currentIndex = 0;
char buffer[ 64 ]; // Hope that 64 is enough for 1 parameter
struct point newPos;

newPos.x = 0.0;
newPos.y = 0.0;

// Needs to interpret
// G1 for moving
// G4 P300 (wait 150ms)
// G1 X60 Y30
// G1 X30 Y50
// M300 S30 (pen down)
// M300 S50 (pen up)
// Discard anything with a (
// Discard any other command!

while( currentIndex < charNB ) {
switch ( line[ currentIndex++ ] ) { // Select command, if any
case 'U':
penUp();
break;
case 'D':
penDown();
break;
case 'G':
buffer[0] = line[ currentIndex++ ]; // /!\ Dirty - Only works with 2 digit commands
// buffer[1] = line[ currentIndex++ ];
// buffer[2] = '\0';
buffer[1] = '\0';

switch ( atoi( buffer ) ){ // Select G command
case 0: // G00 & G01 - Movement or fast movement. Same here
case 1:
// /!\ Dirty - Suppose that X is before Y
char* indexX = strchr( line+currentIndex, 'X' ); // Get X/Y position in the string (if any)
char* indexY = strchr( line+currentIndex, 'Y' );
if ( indexY <= 0 ) {
newPos.x = atof( indexX + 1);
newPos.y = actuatorPos.y;
}
else if ( indexX <= 0 ) {
newPos.y = atof( indexY + 1);
newPos.x = actuatorPos.x;
}
else {
newPos.y = atof( indexY + 1);
indexY = '\0';
newPos.x = atof( indexX + 1);
}
drawLine(newPos.x, newPos.y );
// Serial.println("ok");
actuatorPos.x = newPos.x;
actuatorPos.y = newPos.y;
break;
}
break;
case 'M':
buffer[0] = line[ currentIndex++ ]; // /!\ Dirty - Only works with 3 digit commands
buffer[1] = line[ currentIndex++ ];
buffer[2] = line[ currentIndex++ ];
buffer[3] = '\0';
switch ( atoi( buffer ) ){
case 300:
{
char* indexS = strchr( line+currentIndex, 'S' );
float Spos = atof( indexS + 1);
// Serial.println("ok");
if (Spos == 30) {
penDown();
}
if (Spos == 50) {
penUp();
}
break;
}
case 114: // M114 - Repport position
Serial.print( "Absolute position : X = " );
Serial.print( actuatorPos.x );
Serial.print( " - Y = " );
Serial.println( actuatorPos.y );
break;
default:
Serial.print( "Command not recognized : M");
Serial.println( buffer );
}
}
}



}



* Draw a line from (x0;y0) to (x1;y1).
* int (x1;y1) : Starting coordinates
* int (x2;y2) : Ending coordinates

void drawLine(float x1, float y1) {

if (verbose)
{
Serial.print("fx1, fy1: ");
Serial.print(x1);
Serial.print(", ");
Serial.print(y1);
Serial.println("");
}

// Bring instructions within limits
if (x1 >= Xmax) {
x1 = Xmax;
}
if (x1 <= Xmin) {
x1 = Xmin;
}
if (y1 >= Ymax) {
y1 = Ymax;
}
if (y1 <= Ymin) {
y1 = Ymin;
}

if (verbose)
{
Serial.print("Xpos, Ypos: ");
Serial.print(Xpos);
Serial.print(", ");
Serial.print(Ypos);
Serial.println("");
}

if (verbose)
{
Serial.print("x1, y1: ");
Serial.print(x1);
Serial.print(", ");
Serial.print(y1);
Serial.println("");
}

// Convert coordinates to steps
x1 =
y1 =
float x0 = Xpos;
float y0 = Ypos;

// Let's find out the change for the coordinates
long dx = abs(x1-x0);
long dy = abs(y1-y0);
int sx = x0<x1 ? StepInc : -StepInc;
int sy = y0<y1 ? StepInc : -StepInc;

long i;
long over = 0;

if (dx > dy) {
for (i=0; i<dx; ++i) {
myStepperX.onestep(sx, STEP);
over+=dy;
if (over>=dx) {
over-=dx;
myStepperY.onestep(sy, STEP);
}
delay(StepDelay);
}
}
else {
for (i=0; i<dy; ++i) {
myStepperY.onestep(sy, STEP);
over+=dx;
if (over>=dy) {
over-=dy;
myStepperX.onestep(sx, STEP);
}
delay(StepDelay);
}
}

if (verbose)
{
Serial.print("dx, dy:");
Serial.print(dx);
Serial.print(", ");
Serial.print(dy);
Serial.println("");
}

if (verbose)
{
Serial.print("Going to (");
Serial.print(x0);
Serial.print(", ");
Serial.print(y0);
Serial.println(")");
}

// Delay before any next lines are submitted
delay(LineDelay);
// Update the positions
Xpos = x1;
Ypos = y1;
}

// Raises pen
void penUp() {
penServo.write(penZUp);
delay(penDelay);
Zpos=Zmax;
digitalWrite(15, LOW);
digitalWrite(16, HIGH);
if (verbose) {
S

whiemp