Data Logger Shield + Motor Shield Compatibility?

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
designCPU
 
Posts: 41
Joined: Sun Aug 24, 2014 2:24 pm

Data Logger Shield + Motor Shield Compatibility?

Post by designCPU »

Hi. I'm using three of the v2 Adafruit Motor Shields, stacked, each running four twelve 12VDC computer fans. I have buttons connected to the system that allow the user to change settings for each of the fans. And I'd like to incorporate the Data Logger Shield to save these settings in case the system is is unplugged. Is this Motor Shield configuration compatible with the Data Logger Shield?

User avatar
Franklin97355
 
Posts: 23912
Joined: Mon Apr 21, 2008 2:33 pm

Re: Data Logger Shield + Motor Shield Compatibility?

Post by Franklin97355 »

The logger shield uses i2c address 0x68. If you are not using that for your motor drivers you should be OK.

User avatar
designCPU
 
Posts: 41
Joined: Sun Aug 24, 2014 2:24 pm

Re: Data Logger Shield + Motor Shield Compatibility?

Post by designCPU »

Thanks!

User avatar
designCPU
 
Posts: 41
Joined: Sun Aug 24, 2014 2:24 pm

Re: Data Logger Shield + Motor Shield Compatibility?

Post by designCPU »

More problems. There seems to be some kind of issue between my R3 Uno, Data Logging Shield, V2 Motor Shield, and Quad Alphanumeric Display. I should note that my previous setup didn't have the SD shield or code for data logging, and everything worked fine. When I introduce the Data Logging Shield into the mix, my program doesn't get beyond the setup block. I thought it might be a conflict caused by chip select pin 10 on the SD shield, but when I omit the code initializing the quad-alphanumeric display, the motor and SD card shields play nice. I think I've isolated the offending lines of code:

Code: Select all

#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <SD.h>
#include <Adafruit_MotorShield.h>

…
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *m1 = AFMS.getMotor(1);
Adafruit_DCMotor *m2 = AFMS.getMotor(2);
Adafruit_DCMotor *m3 = AFMS.getMotor(3);
Adafruit_DCMotor *m4 = AFMS.getMotor(4);
  

void setup() {
   Serial.begin(9600);  
   pinMode(10, OUTPUT);
   …

   if (SD.begin(10)) {
      Serial.println("SD CARD INITIALIZATION DONE.");  
   } else {
      Serial.println("SD CARD INITIALIZATION FAILED!");
     }
   …
   
   Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();
   alpha4.begin(0x71);   // SEEMS THAT THE ISSUE IS EITHER HERE OR IN THE AFMS.begin() LINE OF CODE
   alpha4.writeDigitRaw(3, 0x0);
   alpha4.writeDigitRaw(0, 0xFFFF);
   alpha4.writeDisplay();
   delay(150);
   ...

   AFMS.begin();     // SEEMS THAT THE ISSUE IS EITHER HERE OR IN THE alpha4.begin(0x71) LINE OF CODE
   …
}

...

If it's an incompatibility between the included libraries, maybe I'm just out of luck. I've tried re-ordering things, and nothing resolves the issue. Any ideas? Will all of these nightmares go away if I use the Adafruit I2C FRAM Breakout instead of the Data Logging Shield?

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Data Logger Shield + Motor Shield Compatibility?

Post by adafruit_support_mike »

The Motor Shield, SD breakout, and LED backpack are all compatible with each other in general, but their I2C addresses fall in the same range.. 0x68 for the Data Logger's RTC, 0x70 for the backpack, and 0x60-0x7F for the Motor Shield.

You said at the beginning that you're using three Motor Shields. What are their addresses?

User avatar
designCPU
 
Posts: 41
Joined: Sun Aug 24, 2014 2:24 pm

Re: Data Logger Shield + Motor Shield Compatibility?

Post by designCPU »

Their addresses are 0x60, 0x61 and 0x62. The LCD Backpack was modified to have address 0x71. I should mention that I tried to reassign Chip Select Pin #10 on the Adafruit Data Logging Shield by cutting its trace and tying CS to another digital pin, revising the code accordingly. That apparently killed the shield, because it doesn't even run the example ReadWrite program from the SD library. I replaced the Data Logging Shield with a Seeedstudio v3 SD Card Shield. This didn't seem to fix anything. I commented out all of the code, then gradually un-commented it, and now everything works. I have no idea why, but I'll take it. In case anyone's interested, here's the code:

Code: Select all

/* 
  - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - -

    Using the Adafruit Motor Shield v2 to randomly switch computer fans on and off.

    Two buttons connected to the Arduino allow the user to choose a different sleep
    interval for each of the 12 fans.
    
    A 4-character alphanumeric display shows which fan is currently selected, and its
    sleep interval. 
    
    The Data Logging Shield autosaves the current fan settings into a text file. The
    settings are retained when the unit is powered off, then retrieved when it's
    powered on.

    

    2014 Shawn Jackson

  - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - -
*/

#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <SD.h>
#include <Adafruit_MotorShield.h>

// To save memory, use #define directive to enable
// on/off toggling of all Serial.print(F() statements.
//#define DEBUG
//#define DEBUG_EchoFanOnOff
//#define DEBUG_CheckUserChanges
//#define DEBUG_NewInterval
//#define DEBUG_SDCardStatus
//#define DEBUG_SDReadWrite

File myFile;
char *filename = "test.txt";

unsigned int h, i, j, k, m, n, p;
unsigned long lastSaveTime;

const int fanSelectPin = 2;    // arduino pin number for the 'fan select' button
const int intrvlSelPin = 4;    // arduino pin number for the 'interval select' button
const int sdChipSelectPin = 10;
const int FANSELECT = 1;
const int INTRVLSELECT = 2;
const int fanCount = 12;

int button1State;             // Current reading from the input pin, to select motor
int button2State;             // Current reading from the input pin, to control motor sleep interval
int lastButton1State = LOW;   // Previous reading from the input pin
int lastButton2State = LOW;   // ...

// Current selected fan. Range is between 0 and fanCount.
// When currentFan is 0, no fans are selected.
int currentFan = 0;

// 0 default values mean all fans are off on start
int fanSettings[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int previousSettings[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};


// These variables increase quickly, need to declare as 'long'.
unsigned long lastDebounceTime1 = 0;  // last time the motor selection output pin was toggled
unsigned long lastDebounceTime2 = 0;  // last time the sleep interval output pin was toggled
const long debounceDelay = 50;    // the debounce time; increase if the output flickers


Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();
char onesdigit1 = '*', tensdigit1 = '*';
char onesdigit2 = '-', tensdigit2 = '-';

const int motorShieldCount = 3;
const int motorsPerShield = 4;
const int numMotors = motorShieldCount * motorsPerShield;

// Whether or not the fan is currently running
boolean fansRunning[numMotors] = {
  false, false, false, false,
  false, false, false, false,
  false, false, false, false};

// Whether or not the fan is currently active
boolean activeStatus[numMotors] = {
  false, false, false, false,
  false, false, false, false,
  false, false, false, false};


// Keep track of elapsed time overall, and for each fan
unsigned long currentMillis;
unsigned long previousMils[numMotors] = {
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0};


const unsigned int minSleep = 0;      // minimum time between switching on fan
const unsigned int maxSleep = 20;     // maximum time between switching on fan
unsigned int onInterval = 3;          // length of time fan should remain on

unsigned long offIntervals[numMotors] = {
  0,0,0,0,
  0,0,0,0,
  0,0,0,0};

// Assign each stacked shield a different I2C address
Adafruit_MotorShield AFMS[motorShieldCount] = {
  Adafruit_MotorShield(0x60),
  Adafruit_MotorShield(0x61),
  Adafruit_MotorShield(0x62)
};

Adafruit_DCMotor *dcMotors[numMotors] = {
   AFMS[0].getMotor(1), AFMS[0].getMotor(2), AFMS[0].getMotor(3), AFMS[0].getMotor(4),
   AFMS[1].getMotor(1), AFMS[1].getMotor(2), AFMS[1].getMotor(3), AFMS[1].getMotor(4),
   AFMS[2].getMotor(1), AFMS[2].getMotor(2), AFMS[2].getMotor(3), AFMS[2].getMotor(4)};

int fanSpeed = 255; // A value between 0 and 255


  

void setup() {
  Serial.begin(9600);
  Serial.println(F("\n\n+ + + + + + + + + + + + + + + + + + + + + + + + +\n"));
  Serial.println(F("Controlling Fans with Adafruit Motor Shield v2"));
  #ifdef DEBUG
    Serial.println(F("\n| DEBUGGING IS ON"));
  #else
    Serial.println(F("\n| DEBUGGING IS OFF"));
  #endif

  pinMode(fanSelectPin, INPUT);
  pinMode(intrvlSelPin, INPUT);

  // PREPARE SD CARD FOR I/O
  pinMode(sdChipSelectPin, OUTPUT);
  if (!SD.begin(sdChipSelectPin)) {
    #ifdef DEBUG_SDCardStatus
      Serial.println(F("SD CARD INITIALIZATION FAILED!"));  
      Serial.println();
    #endif
  } else {
    #ifdef DEBUG_SDCardStatus
      Serial.println(F("SD CARD INITIALIZATION OK!"));
      Serial.println();
    #endif
  }
  
  // START ALPHANUMERIC DISPLAY
  initDisplay();
  
  // READY THE MOTOR SHIELDS FOR COMMANDS
  AFMS[0].begin();
  AFMS[1].begin();
  AFMS[2].begin();

//  #ifdef DEBUG
//    Serial.println(F("\n| DEBUGGING IS ON"));
//  #else
//    Serial.println(F("\n| DEBUGGING IS OFF"));
//  #endif
//  Serial.print(F("| NO FANS SELECTED\n\n"));

  // Set the speed of the fans (0 is off, 255 is high)
  for(m = 0; m < motorShieldCount; m++) {
    for(n = 0; n < motorsPerShield; n++) {
      dcMotors[m * motorsPerShield + n] -> setSpeed(fanSpeed);
    }
  }

  delay(2000);
  initializeFans();
  #ifdef DEBUG
    Serial.print(F("| NO FANS SELECTED\n\n"));
  #endif
  lastSaveTime = millis();
}


void loop() {
  currentMillis = millis();
  for(p = 0; p < numMotors; p++) {
    if(activeStatus[p]) {
      checkFan(p);
    }
  }
  
  // HANDLE FAN SELECTION BUTTON PRESSES
  int reading1 = digitalRead(fanSelectPin);
  if (reading1 != lastButton1State) {
    // reset the debouncing timer
    lastDebounceTime1 = millis();
  }
  checkButton(reading1, FANSELECT);
  // save the reading.  Next time through the loop,
  // it'll be the lastButton1State:
  lastButton1State = reading1;


  // HANDLE INTERVAL SELECTION BUTTON PRESSES
  int reading2 = digitalRead(intrvlSelPin);
  if (reading2 != lastButton2State) {
    lastDebounceTime2 = millis();
  }  
  checkButton(reading2, INTRVLSELECT);
  lastButton2State = reading2;

  // EVERY 5 SECONDS, WE'LL CHECK TO SEE IF THE USER MADE ANY CHANGES
  // TO THE FAN INTERVALS. IF SHE DID, WE'LL UPDATE THE TEXT FILE
  // CONTAINING THE SETTINGS FOR ALL THE FANS.
  //
  // FILE NAME:      intervals.txt
  // 
  // FILE CONTENTS:  SINGLE LINE OF TEXT. NUMBERS, SEPARATED BY A SPACE,
  //                 REPRESENTING EACH FAN'S SLEEP INTERVAL.
  //
  //                 Example:
  //                 5 2 17 16 7 14 9 18 5 13 0 8
  //
  if(millis() - lastSaveTime >= 5000) {
    #ifdef DEBUG_CheckUserChanges
    Serial.print("\nPROGRAM RUN TIME: ");
    Serial.print(millis()/1000);
    Serial.print(F(" SECONDS. CHECKING WHETHER FAN SETTINGS HAVE CHANGED...\n"));
    #endif
    updateFileIfSettingsChanged();
    lastSaveTime = millis();
  }
}

void checkFan(int selection) {
  unsigned long elapsed = currentMillis - previousMils[selection];  // Calculate elapsed time
  
  if(fansRunning[selection] == false) {
    if(elapsed > offIntervals[selection]) {
      // Randonly generate new wait interval
      offIntervals[selection] = random(0, fanSettings[selection] * 1000);
      
      #ifdef DEBUG_NewInterval
        Serial.print(F("||: New sleep time for Fan "));
        Serial.print(selection + 1);
        Serial.print(F(" is "));
        Serial.print((float)offIntervals[selection]/1000);
        Serial.println(F(" seconds.  "));
      #endif
      
      previousMils[selection] = currentMillis;
      fansRunning[selection] = true;
      dcMotors[selection] -> run(FORWARD);
      #ifdef DEBUG_EchoFanOnOff
        printStatus(selection + 1, true);
      #endif
    }
  } else {
    if(elapsed > onInterval * 1000) {
      previousMils[selection] = currentMillis;
      fansRunning[selection] = false;
      dcMotors[selection] -> run(RELEASE);
      #ifdef DEBUG_EchoFanOnOff
        printStatus(selection + 1, false);
      #endif
    }
  }  
}



void checkButton (int reading, int option) {
  switch(option) {
    case FANSELECT:
      if ((millis() - lastDebounceTime1) > debounceDelay) {
        // Whatever the reading is at, it's been there for longer than
        // the debounce delay, so take it as the actual current state:
    
        // If the button state has changed:
        if (reading != button1State) {
          button1State = reading;
          // Only do something if the new button state is HIGH
          if (button1State == HIGH) {
            #ifdef DEBUG
              Serial.println(F("\n- - - - - - - -"));
            #endif
            currentFan = (currentFan < fanCount) ? (currentFan + 1) : 0;
            if(currentFan == 0) {
              #ifdef DEBUG
                Serial.print(F("NO FANS SELECTED.\n"));
              #endif
              onesdigit1 = tensdigit1 = '*';
              onesdigit2 = tensdigit2 = '-';
            }
            else {
              onesdigit1 = '0' + (currentFan % 10);
              tensdigit1 = '0' + ((currentFan / 10) % 10);
              if(fanSettings[currentFan - 1] == 0) {
                onesdigit2 = tensdigit2 = '-';
              }
              else {
                onesdigit2 = '0' + (1 * fanSettings[currentFan - 1] % 10);
                tensdigit2 = '0' + ((1 * fanSettings[currentFan - 1] / 10) % 10);
              }
              #ifdef DEBUG
                Serial.print(F("FAN "));
                Serial.print(currentFan);
                Serial.print(F(" SELECTED.\n"));
                if(fanSettings[currentFan - 1] > 0) {
                  Serial.print(F("||: Current sleep interval for Fan "));
                  Serial.print(currentFan);
                  Serial.print(F(" is "));
                  Serial.print((float)offIntervals[currentFan - 1]/1000);
                  Serial.println(F(" seconds."));
                } else {
                  Serial.print(F("[]: Fan "));
                  Serial.print(currentFan);
                  Serial.print(F(" is currently off."));
                }
                Serial.println();
              #endif
            }
          }
        }
      }      
      break;
    
    case INTRVLSELECT:
      if ((millis() - lastDebounceTime2) > debounceDelay) {
        if (reading != button2State) {
          button2State = reading;
          if (button2State == HIGH && currentFan > 0 && currentFan < fanCount + 1) {
            fanSettings[currentFan - 1] = (fanSettings[currentFan - 1] < maxSleep) ? (fanSettings[currentFan - 1] + 1) : 0;
            if(fanSettings[currentFan - 1] == 0) {
              onesdigit2 = tensdigit2 = '-';
              #ifdef DEBUG
                Serial.print(F("[]: Fan "));
                Serial.print(currentFan);
                Serial.print(F(" is now offline. Press the button to switch this fan back online."));
              #endif
              fansRunning[currentFan - 1] = false;
              dcMotors[currentFan - 1] -> run(RELEASE);
              activeStatus[currentFan - 1] = false;
            }
            else {
              onesdigit2 = '0' + (1 * fanSettings[currentFan - 1] % 10);
              tensdigit2 = '0' + ((1 * fanSettings[currentFan - 1] / 10) % 10);
              #ifdef DEBUG
                Serial.print(F(">>: Sleep range of Fan "));
                Serial.print(currentFan);
                Serial.print(F(" is now between "));
                Serial.print(minSleep);
                Serial.print(F(" and "));
                Serial.print(minSleep + 1 * fanSettings[currentFan - 1]);
                Serial.print(F(" seconds."));
              #endif
              activeStatus[currentFan - 1] = true;
              previousMils[currentFan - 1] = currentMillis;
              dcMotors[currentFan - 1] -> run(FORWARD);
            }
            #ifdef DEBUG
              Serial.println();
            #endif
          }
        }
      } 
      break;
  }
  alpha4.writeDigitAscii(0, tensdigit1);
  alpha4.writeDigitAscii(1, onesdigit1);
  alpha4.writeDigitAscii(2, tensdigit2);
  alpha4.writeDigitAscii(3, onesdigit2);
  alpha4.writeDisplay();  
}


void printStatus(int s1, boolean state) {
      Serial.print(F("++: FAN "));
      if(s1 < 10) {
        Serial.print('0');
      }
      Serial.print(s1);
      Serial.println(state ? " ON" : " OFF");
}















/* SD CARD I/O FUNCTIONS */
void errorMsg() {
  #ifdef DEBUG
  Serial.print(F("ERROR OPENING FILE "));
  Serial.print(filename);
  Serial.println();
  #endif
}


String fansArrayToString() {
  String settingsList = "";
  for(h = 0; h < fanCount; h++) {
    settingsList += String(fanSettings[h]);
    if(h < fanCount-1) {
      settingsList += ' ';
    }
  }
  return settingsList;
}

void initializeFans() {
  // WHEN ARDUINO IS PLUGGED IN, IF THERE'S A FAN SETTINGS
  // FILE, READ IT INTO fanSettings[] ARRAY

  // IF THIS initializeFans() FUNCTION FAILS BECAUSE THE
  // SD CARD OR CONTENTS CAN'T BE ACCESSED, WE'LL HAVE THE
  // INITIALIZED fanSettings[] ARRAY AS BACKUP. SO THE PROGRAM
  // CAN STILL MOVE FORWARD IF SOMETHING'S WRONG WITH THE
  // SD CARD.

  int index = 0;

  if(SD.exists(filename)) {
    myFile = SD.open(filename);
    if (myFile) {
      #ifdef DEBUG_SDReadWrite    
        Serial.println();
        Serial.print(F("PREVIOUSLY SAVED SLEEP RANGES LOADED FROM FILE "));
        Serial.println(filename);
        Serial.println(F("- - - - - - - - - - - - - - - - - - - - - - - - - - - -"));
      #endif
      while (myFile.available() && index < fanCount) {
        fanSettings[index] = myFile.parseInt();
        previousSettings[index] = fanSettings[index];
        offIntervals[index] = random(0, fanSettings[index] * 1000);

        #ifdef DEBUG_SDReadWrite
          Serial.print(F(".. FAN "));
          if(index + 1 < 10) {
            Serial.print('0');
          }
          Serial.print(index + 1);
          Serial.print(F(" | RANDOM SLEEP RANGE IS "));
          Serial.print(minSleep);
          Serial.print(F(" - "));
          if(fanSettings[index] < 10) {
            Serial.print(' ');
          }          
          Serial.print(minSleep + 1 * fanSettings[index]);
          Serial.print(F(" SECONDS"));
          Serial.println();
        #endif

        if(fanSettings[index] > 0) {
          activeStatus[index] = true;
          dcMotors[index] -> run(FORWARD);
          // ADDING 120ms ENSURES THAT IF THE UNIT WAS JUST NOW POWERED ON, AND
          // THE FAN WAS PREVIOUSLY SET TO 'ON', THIS FAN WILL ACTUALLY PAUSE A
          // SHORT MOMENT BEFORE SWITCHING ON
          previousMils[index] = millis() + 120;
        }

        index += 1;
      }
      myFile.close();
    } else {
      errorMsg();
    }
    
    
    
    
  }
  #ifdef DEBUG_SDReadWrite
    Serial.println();
  #endif
}
//
//
void writeFile() {
  // DELETE PREVIOUS SETTINGS FILE IF
  // IT EXISTS ON THE SD CARD
  if(SD.exists(filename)) {
    #ifdef DEBUG_SDReadWrite
      Serial.print(F("\ERASE PREVIOUS SETTINGS FILE "));
      Serial.print(filename);
      Serial.print(F(" ... "));
    #endif
    SD.remove(filename);
    delay(320);
    #ifdef DEBUG_SDReadWrite
      Serial.print(F("OK"));
      Serial.println();
    #endif
  }

  // CREATE NEW SETINGS FILE AND SAVE
  // OUR CURRENT FAN SETTINGS.
  myFile = SD.open(filename, FILE_WRITE);
  if (myFile) {
    String s = fansArrayToString();
    #ifdef DEBUG_SDReadWrite
      Serial.print(F("\nAUTOSAVE FAN SETTINGS FILE "));
      Serial.print(filename);
      Serial.print(F(" ... "));
    #endif

    myFile.println(s);
    myFile.close();
    delay(320);    
    #ifdef DEBUG_SDReadWrite
      Serial.println(F("OK"));
      Serial.println(s);
    #endif
  } 
  else {
    errorMsg();
  }
}


// IF FAN SETTINGS ARE DIFFERENT FROM PREVIOUSLY SAVED VALUES,
// UPDATE THE SETTINGS FILE.
void updateFileIfSettingsChanged() {
  if(settingsChanged()) {
    #ifdef DEBUG
    Serial.println(F("USER CHANGED FAN SETTINGS. UPDATING FILE..."));
    #endif
    writeFile();
    for(j = 0; j < fanCount; j++) {
      previousSettings[j] = fanSettings[j];
    }
  }
}


// COMPARE PREVIOUS AND CURRENT FAN SETTINGS TO DETERMINE
// WHETHER THEY ARE IDENTICAL
boolean settingsChanged() {
  for(k = 0; k < sizeof(previousSettings)/sizeof(previousSettings[0]); k++) {
    if(previousSettings[k] != fanSettings[k]) {
      return true;
    }
  }
  return false;
}


// INITIATE QUAD ALPHANUMERIC LED DISPLAY
void initDisplay() {
  // WE ASSIGNED OUR I2C ADDRESS TO 0x71 USING THE
  // JUMPERS ON THE LCD BACKPACK. THAT ADDRESS MUST
  // MATCH THE ONE WE SPECIFY IN alpha4.begin(****);
  alpha4.begin(0x71);  // pass in the address

  // ANIMATED SEQUENCE OF CHARACTERS SIGNIFIES
  // THAT WE'VE JUST TURNED IT ON
  alpha4.writeDigitRaw(3, 0x0);
  alpha4.writeDigitRaw(0, 0xFFFF);
  alpha4.writeDisplay();
  delay(120);
  alpha4.writeDigitRaw(0, 0x0);
  alpha4.writeDigitRaw(1, 0xFFFF);
  alpha4.writeDisplay();
  delay(120);
  alpha4.writeDigitRaw(1, 0x0);
  alpha4.writeDigitRaw(2, 0xFFFF);
  alpha4.writeDisplay();
  delay(120);
  alpha4.writeDigitRaw(2, 0x0);
  alpha4.writeDigitRaw(3, 0xFFFF);
  alpha4.writeDisplay();
  delay(120);
  alpha4.clear();
  alpha4.writeDisplay();
  delay(200);
  alpha4.writeDigitAscii(0, tensdigit1);
  delay(120);
  alpha4.writeDisplay();
  alpha4.writeDigitAscii(1, onesdigit1);
  delay(120);
  alpha4.writeDisplay();
  alpha4.writeDigitAscii(2, tensdigit2);
  delay(120);
  alpha4.writeDisplay();
  alpha4.writeDigitAscii(3, onesdigit2);
  delay(120);
  alpha4.writeDisplay();
}

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Data Logger Shield + Motor Shield Compatibility?

Post by adafruit_support_mike »

Ah, one of those..

They happen and generally defy explanation. As long as everything works the way it should now, you win. ;-)

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”