# Question
Title: Code will not run when Serial Monitor is not open
My code runs perfectly as long as the serial port is open. However if I connect it to external power, or even if I just try to run it plugged into my computer with the Serial Monitor not open, nothing happens. My project doesn't need any serial interaction, it will operate on its own far from any computers. I have it in here to help me debug.

The sticking point appears to be with `if (morseInput.available())` on line 63.

Here is everything, including the libraries I am using:

Morse EnDecoder.h

```
#ifndef MorseEnDecoder_H
#define MorseEnDecoder_H

#if (ARDUINO <  100)
#include <WProgram.h>
#else
#include <Arduino.h>
#endif

#define MORSE_AUDIO true
#define MORSE_KEYER false
#define MORSE_ACTIVE_LOW true
#define MORSE_ACTIVE_HIGH false

class morseDecoder
{
public:
morseDecoder(int decodePin, boolean listenAudio, boolean morsePullup);
void decode();
void setspeed(int value);
char read();
boolean available();
int AudioThreshold;
long debounceDelay;     // the debounce time. Keep well below dotTime!!
boolean morseSignalState;
private:
int morseInPin;         // The Morse input pin
int audioSignal;
int morseTablePointer;
int wpm;                // Word-per-minute speed
long dotTime;           // morse dot time length in ms
long dashTime;
long wordSpace;
boolean morseSpace;     // Flag to prevent multiple received spaces
boolean gotLastSig;     // Flag that the last received morse signal is decoded as dot or dash
boolean morseKeyer;
boolean lastKeyerState;
boolean morseAudio;
boolean activeLow;
long markTime;          // timers for mark and space in morse signal
long spaceTime;         // E=MC^2 ;p
long lastDebounceTime;  // the last time the input pin was toggled
long currentTime;       // The current (signed) time
char decodedMorseChar;  // The last decoded Morse character
};

class morseEncoder
{
public:
morseEncoder(int encodePin);
void encode();
void setspeed(int value);
void write(char temp);
boolean available();
int morseSignals;       // nr of morse signals to send in one morse character
char morseSignalString[7];// Morse signal for one character as temporary ASCII string of dots and dashes
private:
char encodeMorseChar;   // ASCII character to encode
boolean sendingMorse;
int wpm;                // Word-per-minute speed
long dotTime;           // morse dot time length in ms
long dashTime;
long wordSpace;
int morseSignalPos;
int sendingMorseSignalNr;
long sendMorseTimer;
long lastDebounceTime;
long currentTime;
protected:
int morseOutPin;
virtual void setup_signal();
virtual void start_signal(bool startOfChar, char signalType);
virtual void stop_signal(bool endOfChar, char signalType);
};

#endif

```

Morse EnDecoder.cpp

```
/*          MORSE ENDECODER

- Morse encoder / decoder classes for the Arduino.

Copyright (C) 2010-2012 raron

GNU GPLv3 license:

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

Details: http://raronoff.wordpress.com/2010/12/16/morse-endecoder/

#include "MorseEnDecoder.h"

// Morse code binary tree table (dichotomic search table)

// ITU with most punctuation (but without non-english characters - for now)
const int morseTreeLevels = 6; // Minus top level, also the max nr. of morse signals
const int morseTableLength = pow(2,morseTreeLevels+1);
const char morseTable[] PROGMEM =
" ETIANMSURWDKGOHVF*L*PJBXCYZQ!*54*3***2&*+****16=/***(*7***8*90*"
"***********?_****\"**.****@***'**-********;!*)*****,****:*******\0";

morseDecoder::morseDecoder(int decodePin, boolean listenAudio, boolean morsePullup)
{
morseInPin = decodePin;
morseAudio = listenAudio;
activeLow = morsePullup;

if (morseAudio == false)
{
pinMode(morseInPin, INPUT);
if (activeLow) digitalWrite (morseInPin, HIGH);
}

// Some initial values
wpm = 13;
AudioThreshold = 700;
debounceDelay = 20;
dotTime = 1200 / wpm;       // morse dot time length in ms
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;

morseTablePointer = 0;

morseKeyer = LOW;
morseSignalState = LOW;
lastKeyerState = LOW;

gotLastSig = true;
morseSpace = true;
decodedMorseChar = '\0';

lastDebounceTime = 0;
markTime = 0;
spaceTime = 0;
}

void morseDecoder::setspeed(int value)
{
wpm = value;
if (wpm <= 0) wpm = 1;
dotTime = 1200 / wpm;
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;
}

boolean morseDecoder::available()
{
if (decodedMorseChar) return true; else return false;
}

char morseDecoder::read()
{
char temp = decodedMorseChar;
decodedMorseChar = '\0';
return temp;
}

void morseDecoder::decode()
{
currentTime = millis();

// Read Morse signals
if (morseAudio == false)
{
// Read the Morse keyer (digital)
morseKeyer = digitalRead(morseInPin);
if (activeLow) morseKeyer = !morseKeyer;

// If the switch changed, due to noise or pressing:
if (morseKeyer != lastKeyerState) lastDebounceTime = currentTime; // reset timer

// debounce the morse keyer
if ((currentTime - lastDebounceTime) > debounceDelay)
{
  // whatever the reading is at, it's been there for longer
  // than the debounce delay, so take it as the actual current state:
  morseSignalState = morseKeyer;

  // differentiante mark and space times
  if (morseSignalState) markTime = lastDebounceTime;
  else spaceTime = lastDebounceTime;
}
} else {
// Read Morse audio signal
audioSignal = analogRead(morseInPin);
if (audioSignal > AudioThreshold)
{
  // If this is a new morse signal, reset morse signal timer
  if (currentTime - lastDebounceTime > dotTime/2)
  {
    markTime = currentTime;
    morseSignalState = true; // there is currently a Morse signal
  }
  lastDebounceTime = currentTime;
} else {
  // if this is a new pause, reset space time
  if (currentTime - lastDebounceTime > dotTime/2 && morseSignalState == true)
  {
    spaceTime = lastDebounceTime; // not too far off from last received audio
    morseSignalState = false;     // No more signal
   }
 }
}

// Decode morse code
if (!morseSignalState)
{
  if (!gotLastSig)
  {
    if (morseTablePointer < morseTableLength/2-1)
    {
    // if pause for more than half a dot, get what kind of signal pulse (dot/dash) received last
    if (currentTime - spaceTime > dotTime/2)
    {
      // if signal for more than 1/4 dotTime, take it as a morse pulse
      if (spaceTime-markTime > dotTime/4)
      {
        morseTablePointer *= 2;  // go one level down the tree
        // if signal for less than half a dash, take it as a dot
        if (spaceTime-markTime < dashTime/2)
        {
           morseTablePointer++; // point to node for a dot
           gotLastSig = true;
        }
        // else if signal for between half a dash and a dash + one dot (1.33 dashes), take as a dash
        else if (spaceTime-markTime < dashTime + dotTime)
        {
           morseTablePointer += 2; // point to node for a dash
           gotLastSig = true;
        }
      }
    }
  } else { // error if too many pulses in one morse character
    //Serial.println("<ERROR: unrecognized signal!>");
    decodedMorseChar = '#'; // error mark
    gotLastSig = true;
    morseTablePointer = 0;
  }
}
// Write out the character if pause is longer than 2/3 dash time (2 dots) and a character received
if ((currentTime-spaceTime >= (dotTime*2)) && (morseTablePointer > 0))
{
  decodedMorseChar = pgm_read_byte_near(morseTable + morseTablePointer);
  morseTablePointer = 0;
}
// Write a space if pause is longer than 2/3rd wordspace
if (currentTime-spaceTime > (wordSpace*2/3) && morseSpace == false)
{
  decodedMorseChar = ' ';
  morseSpace = true ; // space written-flag
}

} else {
// while there is a signal, reset some flags
gotLastSig = false;
morseSpace = false;
}

// Save the morse keyer state for next round
lastKeyerState = morseKeyer;
}

morseEncoder::morseEncoder(int encodePin)
{
  morseOutPin = encodePin;
  this->setup_signal();

// some initial values
sendingMorse = false;
encodeMorseChar = '\0';

wpm = 13;
dotTime = 1200 / wpm;       // morse dot time length in ms
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;
}

void morseEncoder::setspeed(int value)
{
wpm = value;
if (wpm <= 0) wpm = 1;
dotTime = 1200 / wpm;
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;
}

boolean morseEncoder::available()
{
if (sendingMorse) return false; else return true;
}

void morseEncoder::write(char temp)
{
if (!sendingMorse && temp != '*') encodeMorseChar = temp;
}

void morseEncoder::setup_signal()
{
pinMode(morseOutPin, OUTPUT);
digitalWrite(morseOutPin, LOW);
}

void morseEncoder::start_signal(bool startOfChar, char signalType)
{
digitalWrite(morseOutPin, HIGH);
}

void morseEncoder::stop_signal(bool endOfChar, char signalType)
{
digitalWrite(morseOutPin, LOW);
}

void morseEncoder::encode()
{
currentTime = millis();

if (!sendingMorse && encodeMorseChar)
{
// change to capital letter if not
if (encodeMorseChar > 96) encodeMorseChar -= 32;

// Scan for the character to send in the Morse table
int p;
for (p=0; p<morseTableLength+1; p++) if (pgm_read_byte_near(morseTable + p) == encodeMorseChar) break;

if (p >= morseTableLength) p = 0; // not found, but send a space instead

// Reverse binary tree path tracing
int pNode; // parent node
morseSignals = 0;

// Travel the reverse path from position p to the top of the morse table
if (p > 0)
{
  // build the morse signal (backwards morse signal string from last signal to first)
  pNode = p;
  while (pNode > 0)
  {
    if ( (pNode & 0x0001) == 1)
    {
      // It is a dot
      morseSignalString[morseSignals++] = '.';
    } else {
      // It is a dash
      morseSignalString[morseSignals++] = '-';
    }
    // Find parent node
    pNode = int((pNode-1)/2);
  }
} else { // Top of Morse tree - Add the top space character
  // cheating a little; a wordspace for a "morse signal"
  morseSignalString[morseSignals++] = ' ';
}

morseSignalString[morseSignals] = '\0';

// start sending the the character
sendingMorse = true;
sendingMorseSignalNr = morseSignals; // Sending signal string backwards
sendMorseTimer = currentTime;
if (morseSignalString[0] != ' ') this->start_signal(true, morseSignalString[morseSignals-1]);
}

// Send Morse signals to output
if (sendingMorse)
{
char& currSignalType = morseSignalString[sendingMorseSignalNr-1];
bool endOfChar = sendingMorseSignalNr <= 1;
switch (currSignalType)
{
  case '.': // Send a dot (actually, stop sending a signal after a "dot time")
    if (currentTime - sendMorseTimer >= dotTime)
    {
      this->stop_signal(endOfChar, currSignalType);
      sendMorseTimer = currentTime;
      currSignalType = 'x'; // Mark the signal as sent
    }
    break;
  case '-': // Send a dash (same here, stop sending after a dash worth of time)
    if (currentTime - sendMorseTimer >= dashTime)
    {
      this->stop_signal(endOfChar, currSignalType);
      sendMorseTimer = currentTime;
      currSignalType = 'x'; // Mark the signal as sent
    }
    break;
  case 'x': // To make sure there is a pause between signals
    if (sendingMorseSignalNr > 1)
    {
      // Pause between signals in the same letter
      if (currentTime - sendMorseTimer >= dotTime)
      {
        sendingMorseSignalNr--;
        this->start_signal(false, morseSignalString[sendingMorseSignalNr-1]); // Start sending the next signal
        sendMorseTimer = currentTime;       // reset the timer
      }
    } else {
      // Pause between letters
      if (currentTime - sendMorseTimer >= dashTime)
      {
        sendingMorseSignalNr--;
        sendMorseTimer = currentTime;       // reset the timer
      }
    }
    break;
  case ' ': // Pause between words (minus pause between letters - already sent)
  default:  // Just in case its something else
    if (currentTime - sendMorseTimer > wordSpace - dashTime) sendingMorseSignalNr--;
}
if (sendingMorseSignalNr <= 0 )
{
  // Ready to encode more letters
  sendingMorse = false;
  encodeMorseChar = '\0';
}
}
}

```

Morse.h

```
#pragma once
/**
* Generate and send Morse Code on an LED or a speaker. Allow sending
* in a non-blocking manner (by calling a 'continue sending' method
* every so often to turn an LED on/off, or to call tone/noTone appropriately).
*
* All input should be lowercase. Prosigns (SK, KN, etc) have special
* character values #defined.
*/

// for malloc and free, for the new/delete operators
#include <stdlib.h>

// Arduino language types
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#define WPM_DEFAULT 12.0
// PARIS WPM measurement: 50; CODEX WPM measurement: 60 (Wikipedia:Morse_code)
#define DITS_PER_WORD   50
// Pass to SpeakerMorseSender as carrierFrequency to suppress the carrier.
#define CARRIER_FREQUENCY_NONE  -1

// Bitmasks are 1 for dah and 0 for dit, in left-to-right order;
//  the sequence proper begins after the first 1 (a sentinel).
//  Credit for this scheme to Mark VandeWettering K6HX ( brainwagon.org ).
typedef int             morseTiming_t;
typedef unsigned char   morseBitmask_t; // see also MAX_TIMINGS
#define MORSE_BITMASK_HIGH_BIT  B10000000

// sentinel
#define END             0

// the most timing numbers any unit will need; ex: k = on,off,on,off,on,end = 5
#define MAX_TIMINGS     15

// Punctuation and Prosigns
#define PROSIGN_SK  'S'
#define PROSIGN_KN  'K'
#define PROSIGN_BT  'B'
typedef struct {
char c;
morseBitmask_t timing;
} specialTiming;
const specialTiming MORSE_PUNCT_ETC[] = {
{'.',       B1010101},
{'?',       B1001100},
{PROSIGN_SK,    B1000101},
{PROSIGN_KN,    B110110},
{PROSIGN_BT,    B110001},
{END,       B1},
};

// Morse Code (explicit declaration of letter timings)
const morseBitmask_t MORSE_LETTERS[26] = {
/* a */ B101,
/* b */ B11000,
/* c */ B11010,
/* d */ B1100,
/* e */ B10,
/* f */ B10010,
/* g */ B1110,
/* h */ B10000,
/* i */ B100,
/* j */ B10111,
/* k */ B1101,
/* l */ B10100,
/* m */ B111,
/* n */ B110,
/* o */ B1111,
/* p */ B10110,
/* q */ B11101,
/* r */ B1010,
/* s */ B1000,
/* t */ B11,
/* u */ B1001,
/* v */ B10001,
/* w */ B1011,
/* x */ B11001,
/* y */ B11011,
/* z */ B11100,
};

/**
* Define the logic of converting characters to on/off timing,
* and encapsulate the state of one sending-in-progress Morse message.
*
* Subclasses define setOn and setOff for (for example) LED and speaker output.
*/
class MorseSender {
protected:
const unsigned int pin;
// The setOn and setOff methods would be pure virtual,
// but that has compiler issues.
// See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1167672075 .

/**
 * Called to set put the output in 'on' state, during a dit or dah.
 */
virtual void setOn();
virtual void setOff();

/**
 * Called before sending a message. Used for example to enable a
 * carrier. (Noop in the base class.)
 */
virtual void setReady();
virtual void setComplete();

private:
morseTiming_t DIT, DAH;
String message;

// on,off,...,wait,0 list, millis
morseTiming_t timingBuffer[MAX_TIMINGS+1];

// index of the character currently being sent
unsigned int messageIndex;
// timing unit currently being sent
unsigned int timingIndex;

// when this timing unit was started
unsigned long lastChangedMillis;

/**
 * Copy definition timings (on only) to raw timings (on/off).
 * @return the number of 'on' timings copied
 */
int copyTimings(morseTiming_t *rawOut,
    morseBitmask_t definition);

/**
 * Fill a buffer with on,off,..,END timings (millis)
 * @return the index at which to start within the new timing sequence
 */
unsigned int fillTimings(char c);

public:
/**
 * Create a sender which will output to the given pin.
 */
MorseSender(unsigned int outputPin, float wpm=WPM_DEFAULT);

/**
 * To be called during the Arduino setup(); set the pin as OUTPUT.
 */
void setup();

/**
 * Set the words per minute (based on PARIS timing).
 */
void setWPM(float wpm);

/**
 * Set the duration, in milliseconds, of a DIT.
 */
void setSpeed(morseTiming_t duration);

/**
 * Set the message to be sent.
 * This halts any sending in progress.
 */
void setMessage(const String newMessage);

/**
 * Send the entirety of the current message before returning. See the "simple"
 * example, which uses sendBlocking to send one message.
 */
void sendBlocking();

/**
 * Prepare to send and begin sending the current message. After calling this,
 * call continueSending repeatedly until it returns false to finish sending
 * the message. See the "speeds" example, which calls startSending and
 * continueSending on two different senders.
 */
void startSending();

/**
 * Switch outputs on and off (and refill the internal timing buffer)
 * as necessary to continue with the sending of the current message.
 * This should be called every few milliseconds (at a significantly
 * smaller interval than a DIT) to produce a legible fist.
 *
 * @see startSending, which must be called first
 * @return false if sending is complete, otherwise true (keep sending)
 */
boolean continueSending();

void *operator new(size_t size);
void operator delete(void* ptr);
};

/**
* Adapt Morse sending to use the Arduino language tone() and noTone()
* functions, for use with a speaker.
*
* If a carrierFrequency is given, instead of calling noTone, call tone
* with a low frequency. This is useful ex. for maintaining radio links.
*/
class SpeakerMorseSender: public MorseSender {
private:
    unsigned int frequency;
    unsigned int carrFrequency;
protected:
    virtual void setOn();
    virtual void setOff();
    virtual void setReady();
    virtual void setComplete();
public:
    // concert A = 440
    // middle C = 261.626; higher octaves = 523.251, 1046.502
    SpeakerMorseSender(
        int outputPin,
        unsigned int toneFrequency=1046,
        unsigned int carrierFrequency=CARRIER_FREQUENCY_NONE,
        float wpm=WPM_DEFAULT);
};

/**
* Sends Morse on a digital output pin.
*/
class LEDMorseSender: public MorseSender {
protected:
    virtual void setOn();
    virtual void setOff();
public:
    LEDMorseSender(int outputPin, float wpm=WPM_DEFAULT);
};

/**
* Sends Morse on an analog output pin (using PWM). The brightness value is
* between 0 and 255 and is passed directly to analogWrite.
*/
class PWMMorseSender: public MorseSender {
private:
    byte brightness;
protected:
    virtual void setOn();
    virtual void setOff();
public:
    PWMMorseSender(int outputPin, float wpm=WPM_DEFAULT, byte brightness=255);
    void setBrightness(byte brightness);
};

```

morse.cpp

```
// Morse Code sending library

#include <morse.h>

// MorseSender
int MorseSender::copyTimings(
morseTiming_t *rawOut,
morseBitmask_t definition)
{
int t = 0;
boolean foundSentinel = false;
for(morseBitmask_t mask = MORSE_BITMASK_HIGH_BIT;
    mask > 0; mask = mask >> 1)
{
    boolean isDah = (mask & definition) > 0;
    if(!foundSentinel)
    {
        if (isDah) { foundSentinel = true; }
        continue;
    }
    rawOut[2*t] = isDah ? DAH : DIT;
    rawOut[2*t + 1] = DIT;
    t++;
}
return t;
}
unsigned int MorseSender::fillTimings(char c)
{
int t = 0;
unsigned int start = 0;
if (c >= 'a' && c <= 'z')
{
    t = copyTimings(timingBuffer, MORSE_LETTERS[c-'a']);
}
else if (c >= '0' && c <= '9')
{
    int n = c - '0';
    boolean ditsFirst = (n <= 5);
    if (!ditsFirst)
    {
        n -= 5;
    }
    while(t < 5)
    {
        timingBuffer[2*t] = ((t < n) == ditsFirst) ? DIT : DAH;
        timingBuffer[2*t + 1] = DIT;
        t++;
    }
}
else
{
    int s = 0;
    while(MORSE_PUNCT_ETC[s].c != END)
    {
        if(MORSE_PUNCT_ETC[s].c == c)
        {
            t = copyTimings(timingBuffer,
                MORSE_PUNCT_ETC[s].timing);
            break;
        }
        s++;
    }
    if (MORSE_PUNCT_ETC[s].c == END)
    {
        start = t = 1; // start on a space
    }
}

timingBuffer[2*t - 1] = DAH;
timingBuffer[2*t] = END;

return start;
}

// see note in header about pure-virtual-ness
void MorseSender::setOn() {};
void MorseSender::setOff() {};

// noop defaults
void MorseSender::setReady() {};
void MorseSender::setComplete() {};

MorseSender::MorseSender(unsigned int outputPin, float wpm) :
pin(outputPin)
{
setWPM(wpm);
}

void MorseSender::setup() { pinMode(pin, OUTPUT); }

void MorseSender::setWPM(float wpm)
{
setSpeed((morseTiming_t)(1000.0*60.0/(max(1.0, wpm)*DITS_PER_WORD)));
}

void MorseSender::setSpeed(morseTiming_t duration)
{
DIT = max(1, duration);
DAH = 3*DIT;
}

void MorseSender::setMessage(const String newMessage)
{
message = newMessage;

// Force startSending() before continueSending().
messageIndex = message.length();

// If a different message was in progress, make sure it stops cleanly.
if (timingIndex % 2 == 0) {
    setOff();
}
}

void MorseSender::sendBlocking()
{
//Serial.println("Sending blocking: ");
//Serial.println(message);
startSending();
while(continueSending());
}

void MorseSender::startSending()
{
messageIndex = 0;
if (message.length() == 0) { return; }
timingIndex = fillTimings(message[0]);
setReady();
if (timingIndex % 2 == 0) {
    setOn();
    //Serial.print("Starting with on, duration=");
} else {
    //Serial.print("Starting with off, duration=");
}
lastChangedMillis = millis();
//Serial.println((int)timingBuffer[timingIndex]);
}

boolean MorseSender::continueSending()
{
if(messageIndex >= message.length()) { return false; }

unsigned long elapsedMillis = millis() - lastChangedMillis;
if (elapsedMillis < timingBuffer[timingIndex]) { return true; }

timingIndex++;
if (timingBuffer[timingIndex] == END)
{
    messageIndex++;
    if(messageIndex >= message.length()) {
        setOff();
        setComplete();
        return false;
    }
    timingIndex = fillTimings(message[messageIndex]);
}

lastChangedMillis += elapsedMillis;
//Serial.print("Next is       ");
if (timingIndex % 2 == 0) {
    //Serial.print("(on) ");
    setOn();
} else {
    //Serial.print("(off) ");
    setOff();
}
//Serial.println((int)timingBuffer[timingIndex]);

return true;
}

void *MorseSender::operator new(size_t size) { return malloc(size); }
void MorseSender::operator delete(void* ptr) { if (ptr) free(ptr); }

// SpeakerMorseSender

void SpeakerMorseSender::setOn() { tone(pin, frequency); }
void SpeakerMorseSender::setOff() {
if (carrFrequency == CARRIER_FREQUENCY_NONE) {
    noTone(pin);
} else {
    tone(pin, carrFrequency);
}
}
void SpeakerMorseSender::setReady() { setOff(); }
void SpeakerMorseSender::setComplete() { noTone(pin); }
SpeakerMorseSender::SpeakerMorseSender(
int outputPin,
unsigned int toneFrequency,
unsigned int carrierFrequency,
float wpm)
: MorseSender(outputPin, wpm),
frequency(toneFrequency),
carrFrequency(carrierFrequency) {};

// LEDMorseSender

void LEDMorseSender::setOn() { digitalWrite(pin, HIGH); }
void LEDMorseSender::setOff() { digitalWrite(pin, LOW); }
LEDMorseSender::LEDMorseSender(int outputPin, float wpm)
: MorseSender(outputPin, wpm) {};

// PWMMorseSender

void PWMMorseSender::setOn() { analogWrite(pin, brightness); }
void PWMMorseSender::setOff() { analogWrite(pin, 0); }
void PWMMorseSender::setBrightness(byte bright) {
brightness = bright;
}
PWMMorseSender::PWMMorseSender(
    int outputPin,
    float wpm,
    byte bright)
: MorseSender(outputPin, wpm), brightness(bright) {};

```

And finally, here is my code:

```
#include <avr/pgmspace.h>
#include <MorseEnDecoder.h>
#include <stdio.h>
#include <morse.h>
#define PIN_STATUS  13
#define CPU_RESTART_ADDR (uint32_t *)0xE000ED0C
#define CPU_RESTART_VAL 0x5FA0004
#define CPU_RESTART (*CPU_RESTART_ADDR = CPU_RESTART_VAL);

// Pin mapping
const byte morseInPin = 7;
const byte morseOutPin = 13;
String check = "";
String origin = "SOS";
const int maxItems = 3;
int x;
char myArray[maxItems], curChar;
char nextChar;
int i;
int y;

// Instantiate Morse objects
morseDecoder morseInput(morseInPin, MORSE_KEYER, MORSE_ACTIVE_LOW);
morseEncoder morseOutput(morseOutPin);

// Variables dealing with formatting the output somewhat
// by inserting CR's (carriage returns)
long lastTransmissionTime;
long currentTime;
boolean transmissionEnded = true; // Flag to mark old transmission is finished

// Minimum transmission pause time to insert carriage returns (CR)
// Adjust depending on Morse speed. IE 13 wpm = 646 ms between words (no CR).
const long transmissionPaused   = 1000; // Suitable for 13 wpm?

LEDMorseSender sender(PIN_STATUS);

void setup()
{
  Serial.begin(9600);
  Serial.println("Morse EnDecoder Geocache");

  // Setting Morse speed in wpm - words per minute
  // If not set, 13 wpm is default anyway
  morseInput.setspeed(5);
  morseOutput.setspeed(5);

  lastTransmissionTime = (long)millis();
}

void(* resetFunc) (void) = 0; //declare reset function @ address 0

void loop()
{
  currentTime = (long)millis();

  // Need to call these once per loop
  morseInput.decode();
  morseOutput.encode();

  // RECEIVE MORSE (INPUT)
  // If a character is decoded from the input, write it to serial port
  if (morseInput.available())
  {
    char receivedMorse = morseInput.read();
    Serial.print(receivedMorse);
    // A little error checking
    if (receivedMorse == '#') Serial.println("< ERROR:too many morse signals! >");
    morseOutput.write('#');
    morseOutput.encode();

    //Create Array out of receivedMorse Chars

    curChar = 0;
    nextChar = receivedMorse;
    curChar += nextChar;
    myArray[i] = curChar;
    check.concat(myArray[i]);
    Serial.println(check);

    //Check input and respond
    if (check == origin)      //GOOD JOB!!  Your reward is as follows
    {
      Serial.println("check = origin");
      Serial.println(check);
      sender.setup();
      sender.setWPM(5);
      sender.setMessage(String("help is coming"));
      sender.startSending();
    }
    else if (check == "S") {}
    else if (check == "SO") {}
    else if (check == " SOS") {}
    else if (check.length() > 4)
    {
      delay(100);
      Serial.println("resetting");
      delay(500);
      resetFunc();  //call reset
      delay(100);
    }
    else {}
  }
  sender.continueSending();
}

```

# Answer
> 0 votes
It would appear that with this code, the serial.print commands were interfering with the code running as strange as that seems. I was able to delete the offending serial commands and now the code works. With a few tweaks, it should be flawless.

---
Tags: serial, arduino-mega, debugging, debug
---


# Question
Title: Converting uint8_t to String - unexpected result
I'm working on a remote control code for ESP controller. Using ESPwebserver and Fastled. When I try to return a value of an uint8\_t, as a POST response, i got strange result here is the relevant code:

```
uint8_t PaletteBrightness = 255;

server.on("/Sync", HTTP_POST, []() {
String Sync = "PaletteBrightness:" + PaletteBrightness;
    Sync += ":end";
    Serial.println(Sync);
    server.send(200, "text/plain", Sync);
  });

```

The code complies, and runs fine but the result of 'Sync' in both serial, and POST response is:

```
Phase:end

```

Why? What does even Phase mean?
What I want is:

```
PaletteBrightness:255:end

```

Where the 255 is the value of 'uint8\_t PaletteBrightness' Also, there will be more values, to add the 'Sync' string. Just trying to get one right.

# Answer
You should convert your number `uint8_t` into it's ASCII representation before appending it to your string, otherwise you are appending just one character using it's byte representation.

To do so you can use a standard function `itoa()` which has a decent documentation available here.

So change line

```
 String Sync = "PaletteBrightness:" + PaletteBrightness;

```

into

```
 char buffer [4];
 String Sync = "PaletteBrightness:" + itoa(PaletteBrightness, buffer, 10);

```
> 0 votes

---
Tags: esp8266, string
---


# Question
Title: how to get an unofficial WiFi Shield to work?
I just bought these two WiFi Shields -\> http://www.ebay.de/itm/262525969091?\_trksid=p2060353.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

As they arrived I put one of them onto my Arduino Uno R3 and tried if my LED test sketch still works. It did.

After that I tried this WiFi tutorial (https://www.arduino.cc/en/Tutorial/ConnectWithWPA) to play around with the WiFi API a little bit. Sadly it prints to the serial monitor *"WiFi shield not present"* which tells me I missed something when setting up the shield.

I just thought the WiFi shield will be already usable without wiring anything. Surely that might be naive somehow, but hey I'm still a noob ;)

Can you guys tell me or simply point out a tutorial where it tells me what wiring I have to do to at least get pass this *"WiFi shield not present"* check?

Then I just realized that I do not have the "real" Arduino WiFi Shield and therefore the origin WiFi lib won't work for me according to this thread: http://forum.arduino.cc/index.php?topic=371362.0

Sadly I did not received any documenation on how to get this thing to work now. I found A LOT of threads about the "WiFi shield not present" error but none of them solved my specific problem with the shields I bought.

# Answer
> 2 votes
Somewhere it should say this: It is really really difficult to implement enough of the TCP/IP stack on an Uno to handle talking over the Ethernet. In other words, the shield is doing almost all the work. As such, if you don't have any documentation, using this Ethernet shield will be difficult. That said, it looks like this shield is using an ESP8266 which IS widely documented. And if you search around, can even find people creating Arduino / ESP8266 software.

---
Tags: arduino-uno, wifi, shields, library
---


# Question
Title: I swear this worked yesterday!! - mysterious compiler error
I thought I finally had this working yesterday, the code compiled, and executed on the arduino, there were however some small quirks but today I went to fix a small timing issue, but got the following errors instead. Nothing related to the errors was changed, they just showed up, in fact I went back to the original code which was compiling fine yesterday and it won't compile either. The errors are directly below this followed by the libraries which appear to be the cause of the errors. Please help, I just want to get this project finished.

```
Arduino: 1.6.7 (Mac OS X), TD: 1.28-beta1, Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

In file included from /Users/DMYoung1/Library/Arduino15/packages/arduino/hardware/avr/1.6.13/cores/arduino/Arduino.h:28:0,
from /Users/DMYoung1/Documents/Arduino/libraries/Morse_EnDecoder/MorseEnDecoder.h:7,
from /Users/DMYoung1/Documents/Arduino/libraries/Morse_EnDecoder/MorseEnDecoder.cpp:67:
/Users/DMYoung1/Documents/Arduino/libraries/Morse_EnDecoder/MorseEnDecoder.cpp:75:19: error: variable 'morseTable' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
char morseTable[] PROGMEM =
               ^
exit status 1
Error compiling for "Arduino/Genuino Mega or Mega 2560"

```

I am attaching my code and the libraries I am using.

Morse EnDecoder.h

```
#ifndef MorseEnDecoder_H
#define MorseEnDecoder_H

#if (ARDUINO <  100)
#include <WProgram.h>
#else
#include <Arduino.h>
#endif

#define MORSE_AUDIO true
#define MORSE_KEYER false
#define MORSE_ACTIVE_LOW true
#define MORSE_ACTIVE_HIGH false

class morseDecoder
{
public:
morseDecoder(int decodePin, boolean listenAudio, boolean morsePullup);
void decode();
void setspeed(int value);
char read();
boolean available();
int AudioThreshold;
long debounceDelay;     // the debounce time. Keep well below dotTime!!
boolean morseSignalState;
private:
int morseInPin;         // The Morse input pin
int audioSignal;
int morseTablePointer;
int wpm;                // Word-per-minute speed
long dotTime;           // morse dot time length in ms
long dashTime;
long wordSpace;
boolean morseSpace;     // Flag to prevent multiple received spaces
boolean gotLastSig;     // Flag that the last received morse signal is decoded as dot or dash
boolean morseKeyer;
boolean lastKeyerState;
boolean morseAudio;
boolean activeLow;
long markTime;          // timers for mark and space in morse signal
long spaceTime;         // E=MC^2 ;p
long lastDebounceTime;  // the last time the input pin was toggled
long currentTime;       // The current (signed) time
char decodedMorseChar;  // The last decoded Morse character
};

class morseEncoder
{
public:
morseEncoder(int encodePin);
void encode();
void setspeed(int value);
void write(char temp);
boolean available();
int morseSignals;       // nr of morse signals to send in one morse character
char morseSignalString[7];// Morse signal for one character as temporary ASCII string of dots and dashes
private:
char encodeMorseChar;   // ASCII character to encode
boolean sendingMorse;
int wpm;                // Word-per-minute speed
long dotTime;           // morse dot time length in ms
long dashTime;
long wordSpace;
int morseSignalPos;
int sendingMorseSignalNr;
long sendMorseTimer;
long lastDebounceTime;
long currentTime;
protected:
int morseOutPin;
virtual void setup_signal();
virtual void start_signal(bool startOfChar, char signalType);
virtual void stop_signal(bool endOfChar, char signalType);
};

#endif

```

Here is Morse EnDecoder.cpp

```
/*          MORSE ENDECODER

- Morse encoder / decoder classes for the Arduino.

Copyright (C) 2010-2012 raron

GNU GPLv3 license:

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

Details: http://raronoff.wordpress.com/2010/12/16/morse-endecoder/

#include "MorseEnDecoder.h"

// Morse code binary tree table (dichotomic search table)

// ITU with most punctuation (but without non-english characters - for now)
const int morseTreeLevels = 6; // Minus top level, also the max nr. of morse signals
const int morseTableLength = pow(2,morseTreeLevels+1);
const char morseTable[] PROGMEM =
" ETIANMSURWDKGOHVF*L*PJBXCYZQ!*54*3***2&*+****16=/***(*7***8*90*"
"***********?_****\"**.****@***'**-********;!*)*****,****:*******\0";

morseDecoder::morseDecoder(int decodePin, boolean listenAudio, boolean morsePullup)
{
morseInPin = decodePin;
morseAudio = listenAudio;
activeLow = morsePullup;

if (morseAudio == false)
{
pinMode(morseInPin, INPUT);
if (activeLow) digitalWrite (morseInPin, HIGH);
}

// Some initial values
wpm = 13;
AudioThreshold = 700;
debounceDelay = 20;
dotTime = 1200 / wpm;       // morse dot time length in ms
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;

morseTablePointer = 0;

morseKeyer = LOW;
morseSignalState = LOW;
lastKeyerState = LOW;

gotLastSig = true;
morseSpace = true;
decodedMorseChar = '\0';

lastDebounceTime = 0;
markTime = 0;
spaceTime = 0;
}

void morseDecoder::setspeed(int value)
{
wpm = value;
if (wpm <= 0) wpm = 1;
dotTime = 1200 / wpm;
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;
}

boolean morseDecoder::available()
{
if (decodedMorseChar) return true; else return false;
}

char morseDecoder::read()
{
char temp = decodedMorseChar;
decodedMorseChar = '\0';
return temp;
}

void morseDecoder::decode()
{
currentTime = millis();

// Read Morse signals
if (morseAudio == false)
{
// Read the Morse keyer (digital)
morseKeyer = digitalRead(morseInPin);
if (activeLow) morseKeyer = !morseKeyer;

// If the switch changed, due to noise or pressing:
if (morseKeyer != lastKeyerState) lastDebounceTime = currentTime; // reset timer

// debounce the morse keyer
if ((currentTime - lastDebounceTime) > debounceDelay)
{
  // whatever the reading is at, it's been there for longer
  // than the debounce delay, so take it as the actual current state:
  morseSignalState = morseKeyer;

  // differentiante mark and space times
  if (morseSignalState) markTime = lastDebounceTime;
  else spaceTime = lastDebounceTime;
}
} else {
// Read Morse audio signal
audioSignal = analogRead(morseInPin);
if (audioSignal > AudioThreshold)
{
  // If this is a new morse signal, reset morse signal timer
  if (currentTime - lastDebounceTime > dotTime/2)
  {
    markTime = currentTime;
    morseSignalState = true; // there is currently a Morse signal
  }
  lastDebounceTime = currentTime;
} else {
  // if this is a new pause, reset space time
  if (currentTime - lastDebounceTime > dotTime/2 && morseSignalState == true)
  {
    spaceTime = lastDebounceTime; // not too far off from last received audio
    morseSignalState = false;     // No more signal
   }
 }
}

// Decode morse code
if (!morseSignalState)
{
  if (!gotLastSig)
  {
    if (morseTablePointer < morseTableLength/2-1)
    {
    // if pause for more than half a dot, get what kind of signal pulse (dot/dash) received last
    if (currentTime - spaceTime > dotTime/2)
    {
      // if signal for more than 1/4 dotTime, take it as a morse pulse
      if (spaceTime-markTime > dotTime/4)
      {
        morseTablePointer *= 2;  // go one level down the tree
        // if signal for less than half a dash, take it as a dot
        if (spaceTime-markTime < dashTime/2)
        {
           morseTablePointer++; // point to node for a dot
           gotLastSig = true;
        }
        // else if signal for between half a dash and a dash + one dot (1.33 dashes), take as a dash
        else if (spaceTime-markTime < dashTime + dotTime)
        {
           morseTablePointer += 2; // point to node for a dash
           gotLastSig = true;
        }
      }
    }
  } else { // error if too many pulses in one morse character
    //Serial.println("<ERROR: unrecognized signal!>");
    decodedMorseChar = '#'; // error mark
    gotLastSig = true;
    morseTablePointer = 0;
  }
}
// Write out the character if pause is longer than 2/3 dash time (2 dots) and a character received
if ((currentTime-spaceTime >= (dotTime*2)) && (morseTablePointer > 0))
{
  decodedMorseChar = pgm_read_byte_near(morseTable + morseTablePointer);
  morseTablePointer = 0;
}
// Write a space if pause is longer than 2/3rd wordspace
if (currentTime-spaceTime > (wordSpace*2/3) && morseSpace == false)
{
  decodedMorseChar = ' ';
  morseSpace = true ; // space written-flag
}

} else {
// while there is a signal, reset some flags
gotLastSig = false;
morseSpace = false;
}

// Save the morse keyer state for next round
lastKeyerState = morseKeyer;
}

morseEncoder::morseEncoder(int encodePin)
{
  morseOutPin = encodePin;
  this->setup_signal();

// some initial values
sendingMorse = false;
encodeMorseChar = '\0';

wpm = 13;
dotTime = 1200 / wpm;       // morse dot time length in ms
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;

}

void morseEncoder::setspeed(int value)
{
wpm = value;
if (wpm <= 0) wpm = 1;
dotTime = 1200 / wpm;
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;
}

boolean morseEncoder::available()
{
if (sendingMorse) return false; else return true;
}

void morseEncoder::write(char temp)
{
if (!sendingMorse && temp != '*') encodeMorseChar = temp;
}

void morseEncoder::setup_signal()
{
pinMode(morseOutPin, OUTPUT);
digitalWrite(morseOutPin, LOW);
}

void morseEncoder::start_signal(bool startOfChar, char signalType)
{
digitalWrite(morseOutPin, HIGH);
}

void morseEncoder::stop_signal(bool endOfChar, char signalType)
{
digitalWrite(morseOutPin, LOW);
}

void morseEncoder::encode()
{
currentTime = millis();

if (!sendingMorse && encodeMorseChar)
{
// change to capital letter if not
if (encodeMorseChar > 96) encodeMorseChar -= 32;

// Scan for the character to send in the Morse table
int p;
for (p=0; p<morseTableLength+1; p++) if (pgm_read_byte_near(morseTable + p) == encodeMorseChar) break;

if (p >= morseTableLength) p = 0; // not found, but send a space instead

// Reverse binary tree path tracing
int pNode; // parent node
morseSignals = 0;

// Travel the reverse path from position p to the top of the morse table
if (p > 0)
{
  // build the morse signal (backwards morse signal string from last signal to first)
  pNode = p;
  while (pNode > 0)
  {
    if ( (pNode & 0x0001) == 1)
    {
      // It is a dot
      morseSignalString[morseSignals++] = '.';
    } else {
      // It is a dash
      morseSignalString[morseSignals++] = '-';
    }
    // Find parent node
    pNode = int((pNode-1)/2);
  }
} else { // Top of Morse tree - Add the top space character
  // cheating a little; a wordspace for a "morse signal"
  morseSignalString[morseSignals++] = ' ';
}

morseSignalString[morseSignals] = '\0';

// start sending the the character
sendingMorse = true;
sendingMorseSignalNr = morseSignals; // Sending signal string backwards
sendMorseTimer = currentTime;
if (morseSignalString[0] != ' ') this->start_signal(true, morseSignalString[morseSignals-1]);
}

// Send Morse signals to output
if (sendingMorse)
{
char& currSignalType = morseSignalString[sendingMorseSignalNr-1];
bool endOfChar = sendingMorseSignalNr <= 1;
switch (currSignalType)
{
  case '.': // Send a dot (actually, stop sending a signal after a "dot time")
    if (currentTime - sendMorseTimer >= dotTime)
    {
      this->stop_signal(endOfChar, currSignalType);
      sendMorseTimer = currentTime;
      currSignalType = 'x'; // Mark the signal as sent
    }
    break;
  case '-': // Send a dash (same here, stop sending after a dash worth of time)
    if (currentTime - sendMorseTimer >= dashTime)
    {
      this->stop_signal(endOfChar, currSignalType);
      sendMorseTimer = currentTime;
      currSignalType = 'x'; // Mark the signal as sent
    }
    break;
  case 'x': // To make sure there is a pause between signals
    if (sendingMorseSignalNr > 1)
    {
      // Pause between signals in the same letter
      if (currentTime - sendMorseTimer >= dotTime)
      {
        sendingMorseSignalNr--;
        this->start_signal(false, morseSignalString[sendingMorseSignalNr-1]); // Start sending the next signal
        sendMorseTimer = currentTime;       // reset the timer
      }
    } else {
      // Pause between letters
      if (currentTime - sendMorseTimer >= dashTime)
      {
        sendingMorseSignalNr--;
        sendMorseTimer = currentTime;       // reset the timer
      }
    }
    break;
  case ' ': // Pause between words (minus pause between letters - already sent)
  default:  // Just in case its something else
    if (currentTime - sendMorseTimer > wordSpace - dashTime) sendingMorseSignalNr--;
}
if (sendingMorseSignalNr <= 0 )
{
  // Ready to encode more letters
  sendingMorse = false;
  encodeMorseChar = '\0';
}
}
}

```

And finally, here is my code!!

```
#include <avr/pgmspace.h>
#include <MorseEnDecoder.h>
#include <stdio.h>
#include <morse.h>
#define PIN_STATUS  13
#define CPU_RESTART_ADDR (uint32_t *)0xE000ED0C
#define CPU_RESTART_VAL 0x5FA0004
#define CPU_RESTART (*CPU_RESTART_ADDR = CPU_RESTART_VAL);

// Pin mapping
const byte morseInPin = 7;
const byte morseOutPin = 13;
String check = "";
String origin = "SOS";
const int maxItems = 3;
int x;
char myArray[maxItems], curChar;
char nextChar;
int i;
int y;

// Instantiate Morse objects
morseDecoder morseInput(morseInPin, MORSE_KEYER, MORSE_ACTIVE_LOW);
morseEncoder morseOutput(morseOutPin);

// Variables dealing with formatting the output somewhat
// by inserting CR's (carriage returns)
long lastTransmissionTime;
long currentTime;
boolean transmissionEnded = true; // Flag to mark old transmission is finished

// Minimum transmission pause time to insert carriage returns (CR)
// Adjust depending on Morse speed. IE 13 wpm = 646 ms between words (no CR).
const long transmissionPaused   = 1000; // Suitable for 13 wpm?

LEDMorseSender sender(PIN_STATUS);

void setup()
{
Serial.begin(9600);
Serial.println("Morse EnDecoder Geocache");

// Setting Morse speed in wpm - words per minute
// If not set, 13 wpm is default anyway
morseInput.setspeed(5);
morseOutput.setspeed(5);

lastTransmissionTime = (long)millis();

}

void(* resetFunc) (void) = 0; //declare reset function @ address 0

void loop()
{
currentTime = (long)millis();

// Need to call these once per loop
morseInput.decode();
morseOutput.encode();

// RECEIVE MORSE (INPUT)
// If a character is decoded from the input, write it to serial port
if (morseInput.available())
{

char receivedMorse = morseInput.read();
Serial.print(receivedMorse);
// A little error checking
if (receivedMorse == '#') Serial.println("< ERROR:too many morse signals! >");
morseOutput.write('#');
morseOutput.encode();

//Create Array out of receivedMorse Chars

    curChar = 0;
    nextChar = receivedMorse;
    curChar +=nextChar;
    myArray[i] = curChar;
    check.concat(myArray[i]);
    Serial.println(check);

//Check input and respond
if (check == origin)      //GOOD JOB!!  Your reward is as follows
{
Serial.println("check = origin");
Serial.println(check);
sender.setup();
sender.setWPM(5);
sender.setMessage(String("help is coming"));
sender.startSending();
}
else if (check =="S") {}
else if (check == "SO") {}
else if (check == " SOS") {}
else if (check.length() >4)
{
delay(100);
Serial.println("resetting");
delay(500);
resetFunc();  //call reset
delay(100);
}
else {}
}
sender.continueSending();
}

```

# Answer
> 0 votes
Apparently you have made multiple copies of MorseEnDecoder.cpp, some of them modified, because the `morseTable[]` declaration shown in the error message is different than that shown in the code you said is MorseEnDecoder.cpp. Specifically, line 32 of that code is

```
const char morseTable[] PROGMEM =

```

while the error message refers to a line 75 which reads

```
char morseTable[] PROGMEM =

```

The solution is to extirpate extraneous copies and restore MorseEnDecoder.cpp to a correct version.

---
Tags: arduino-mega, compile, debugging, debug, compiler
---


# Question
Title: How to correctly serve a webpage from an SD card
It's been days that I'm trying to figure it out how to edit this perfectly working code in order to load load a webpage from the sd card.

```
#include <SPI.h>
#include <Ethernet2.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 192, 168, 1, 178 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 192, 168, 1, 1 };                   // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port
String readString;
boolean L1chk;
boolean L2chk;
boolean L3chk;
boolean L4chk;
boolean L5chk;
boolean L6chk;
boolean L7chk;
boolean L8chk;
int led;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);

pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          //Serial.print(c);
         }

         //if HTTP request has ended
         if (c == '\n') {
           Serial.println(readString); //print to serial monitor for debuging

           client.println("HTTP/1.1 200 OK"); //send new page
           client.println("Content-Type: text/html");
           client.println();
           client.println("<HTML>");
           client.println("<HEAD>");
           client.println("<meta name='apple-mobile-web-app-capable' content='yes' />");
           client.println("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />");
           client.println("<TITLE>CONTROLLO LEDS</TITLE>");
           client.println("</HEAD>");
           client.println("<BODY>");
           client.println("<H1>FLASHATI</H1>");
           client.println("<hr />");
           client.println("<a href=\"/?1\"\">LED1</a>");
           client.println("<a href=\"/?2\"\">LED2</a>");
           client.println("<a href=\"/?3\"\">LED3</a>");
           client.println("<a href=\"/?4\"\">LED4</a>");
           client.println("<a href=\"/?5\"\">LED5</a>");
           client.println("<a href=\"/?6\"\">LED6</a>");
           client.println("<a href=\"/?7\"\">LED7</a>");
           client.println("<a href=\"/?8\"\">LED8</a>");
           client.println("<br />");
           client.println("<br />");
           client.println("<p>Created by Rui Santos. Visit http://randomnerdtutorials.com for more projects!</p>");
           client.println("<br />");
           client.println("</BODY>");
           client.println("</HTML>");

           delay(1);
           //stopping client
           client.stop();
           //controls the Arduino if you press the buttons
           if (readString.indexOf("?1") >0){
               ledUno();
            }
           if (readString.indexOf("?2") >0){
               ledDue();
            }
            if (readString.indexOf("?3") >0){
               ledTre();
            }
            if (readString.indexOf("?4") >0){
               ledQuattro();
            }
            if (readString.indexOf("?5") >0){
               ledCinque();
            }
            if (readString.indexOf("?6") >0){
               ledSei();
            }
            if (readString.indexOf("?7") >0){
               ledSette();
            }
            if (readString.indexOf("?8") >0){
               ledOtto();
            }
           readString="";
        }

        }
    }
}
}

```

So I came out with this after a lot of research:

```
/*
    Created by Rui Santos
    Visit: http://randomnerdtutorials.com for more arduino projects

    Arduino with Ethernet Shield
*/

#include <SPI.h>
#include <Ethernet2.h>
#include <SD.h>
File webFile;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 192, 168, 1, 178 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 192, 168, 1, 1 };                   // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port
String readString;
boolean L1chk;
boolean L2chk;
boolean L3chk;
boolean L4chk;
boolean L5chk;
boolean L6chk;
boolean L7chk;
boolean L8chk;
int led;

void setup() {
    // Open serial communications and wait for port to open:
    Serial.begin(9600);

    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    // start the Ethernet connection and the server:
    Ethernet.begin(mac);
    server.begin();
    Serial.print("server is at ");
    Serial.println(Ethernet.localIP());
    if (!SD.begin(4)) {
        Serial.println("ERROR - SD card initialization failed!");
        return;    // init failed
    }
    Serial.println("SUCCESS - SD card initialized.");
    // check for index.htm file
    if (!SD.exists("index.htm")) {
        Serial.println("ERROR - Can't find index.htm file!");
        return;  // can't find index file
    }
    Serial.println("SUCCESS - Found index.htm file.");
}

void loop() {
    // Create a client connection
    EthernetClient client = server.available();
    if (client) {
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {
                char c = client.read(); // read 1 byte (character) from client
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                if (c == '\n' && currentLineIsBlank) {
                    // send a standard http response header
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println("Connection: close");
                    client.println();
                    // send web page
                    webFile = SD.open("index.htm");        // open web page file
                    if (webFile) {
                        while(webFile.available()) {
                            client.write(webFile.read()); // send web page to client
                        }

                        webFile.close();
                    }
                    break;

                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                    if (readString.indexOf("?1") >0){
                        ledUno();
                    }
                    if (readString.indexOf("?2") >0){
                        ledDue();
                    }
                    if (readString.indexOf("?3") >0){
                        ledTre();
                    }
                    if (readString.indexOf("?4") >0){
                        ledQuattro();
                    }
                    if (readString.indexOf("?5") >0){
                        ledCinque();
                    }
                    if (readString.indexOf("?6") >0){
                        ledSei();
                    }
                    if (readString.indexOf("?7") >0){
                        ledSette();
                    }
                    if (readString.indexOf("?8") >0){
                        ledOtto();
                    }
                    readString="";
                }
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
                //controls the Arduino if you press the buttons

            }

        }
        delay(1);      // give the web browser time to receive the data
        client.stop();
        if (readString.indexOf("?1") >0){
            ledUno();
        }
        if (readString.indexOf("?2") >0){
            ledDue();
        }
        if (readString.indexOf("?3") >0){
            ledTre();
        }
        if (readString.indexOf("?4") >0){
            ledQuattro();
        }
        if (readString.indexOf("?5") >0){
            ledCinque();
        }
        if (readString.indexOf("?6") >0){
            ledSei();
        }
        if (readString.indexOf("?7") >0){
            ledSette();
        }
        if (readString.indexOf("?8") >0){
            ledOtto();
        }
        readString="";
    }
}

void ledUno(){
    led = 2;
    if (L1chk == 0){                                             //Il Ledled 1 è Spento
        digitalWrite(led, HIGH);
        L1chk = 1;
        return;                   //Led 1 acceso
    }

    if (L1chk == 1){                                             //Il Ledled 1 è Spento
        digitalWrite(led, LOW);
        L1chk = 0;
        return;                   //Led 1 acceso
    }
}

void ledDue(){
    led = 3;
    if (L2chk == 0){                                             //Il Ledled 1 è Spento
        digitalWrite(led, HIGH);
        L2chk = 1;
        return;                   //Led 1 acceso
    }

    if (L2chk == 1){                                             //Il Ledled 1 è Spento
        digitalWrite(led, LOW);
        L2chk = 0;
        return;                   //Led 1 acceso
    }
}

void ledTre(){
    led = 4;
    if (L3chk == 0){                                             //Il Ledled 1 è Spento
        digitalWrite(led, HIGH);
        L3chk = 1;
        return;                   //Led 1 acceso
    }

    if (L3chk == 1){                                             //Il Ledled 1 è Spento
        digitalWrite(led, LOW);
        L3chk = 0;
        return;                   //Led 1 acceso
    }
}

void ledQuattro(){
    led = 5;
    if (L4chk == 0){                                             //Il Ledled 1 è Spento
        digitalWrite(led, HIGH);
        L4chk = 1;
        return;                   //Led 1 acceso
    }

    if (L4chk == 1){                                             //Il Ledled 1 è Spento
        digitalWrite(led, LOW);
        L4chk = 0;
        return;                   //Led 1 acceso
    }
}

void ledCinque(){
    led = 6;
    if (L5chk == 0){                                             //Il Ledled 1 è Spento
        digitalWrite(led, HIGH);
        L5chk = 1;
        return;                   //Led 1 acceso
    }

    if (L5chk == 1){                                             //Il Ledled 1 è Spento
        digitalWrite(led, LOW);
        L5chk = 0;
        return;                   //Led 1 acceso
    }
}

void ledSei(){
    led = 7;
    if (L6chk == 0){                                             //Il Ledled 1 è Spento
        digitalWrite(led, HIGH);
        L6chk = 1;
        return;                   //Led 1 acceso
    }

    if (L6chk == 1){                                             //Il Ledled 1 è Spento
        digitalWrite(led, LOW);
        L6chk = 0;
        return;                   //Led 1 acceso
    }
}

void ledSette(){
    led = 8;
    if (L7chk == 0){                                             //Il Ledled 1 è Spento
        digitalWrite(led, HIGH);
        L7chk = 1;
        return;                   //Led 1 acceso
    }

    if (L7chk == 1){                                             //Il Ledled 1 è Spento
        digitalWrite(led, LOW);
        L7chk = 0;
        return;                   //Led 1 acceso
    }
}

void ledOtto(){
    led = 9;
    if (L8chk == 0){                                             //Il Ledled 1 è Spento
        digitalWrite(led, HIGH);
        L8chk = 1;
        return;                   //Led 1 acceso
    }

    if (L8chk == 1){                                             //Il Ledled 1 è Spento
        digitalWrite(led, LOW);
        L8chk = 0;
        return;                   //Led 1 acceso
    }
}

```

So far the web page is correctly loaded, but the sketch of the LED light logic seems to not work anymore like it was working correctly before. I thought that maybe someone of you guys could help point me in the right direction.

# Answer
It looks that I found the solution to my problem, the first skecth was working correctly because the **SD card is using the pin 4 for his purpose**, so the sketch was working good becuse the SD card was not used here, in the second code where I used th SD card to serve a webpage **was not working anymore not because of the code, but becuse the PIN 4 where I connected a led was used by SDcard** and so it messed up by blinking the LED

**DON'T USE PIN4 WITH AN ETHERNET SHIELD IF YOU PLAN TO USE THE SD CARD**
> 1 votes

---
Tags: shields, ethernet, sd-card, http
---


# Question
Title: Trying to understand bitbanging, shiftIn(), reading EEPROM
Alright, so I have an Atmel 93C66, http://www.atmel.com/Images/doc0172Z.pdf Datasheet and I'm wanting to read whatever is in it.

I copied the following code from this thread http://forum.arduino.cc/index.php?topic=96411.0 and made some changes to it, mainly I deleted the part where it writes:

```
//difining pins for eeprom
int CLOCK =4;
int DATA_OUT =3;
int DATA_IN = 2;
int CHIP_SEL =5;

int low =0;     //low address

byte READ  = 0b1100;                //read instruction

void setup(){

  pinMode(CLOCK ,OUTPUT);
  pinMode(DATA_OUT ,OUTPUT);
  pinMode(DATA_IN ,INPUT);
  pinMode(CHIP_SEL ,OUTPUT);
  digitalWrite(CHIP_SEL ,LOW);
  digitalWrite(CLOCK, LOW);
  Serial.begin(9600);
}

void loop()
{

  for (int i=0;i<=511;i++)
  {
    digitalWrite(CHIP_SEL ,HIGH);
    shiftOut(DATA_OUT,CLOCK,MSBFIRST,READ); //sending READ instruction
    shiftOut(DATA_OUT,CLOCK,MSBFIRST,low);   //sending low address
    byte incoming = shiftIn(DATA_IN,CLOCK,MSBFIRST); //receiving data
    digitalWrite(CHIP_SEL ,LOW);

    Serial.print(low);
    Serial.print("/t");
    Serial.print(incoming, BIN);
    Serial.print("/t");
    Serial.print(incoming, HEX);
    Serial.println():

    low++;       //incrementing low address

  }
  while(1);
}

```

What I'm trying to understand is:

In the 93C66 datasheet page 5, table 6, it says that to read the contents of memory I need to send SB 1, OPCODE 10, and memory address, which I don't know exactly how to do, but I guess the chip wants a 110 (or a HIGH, HIGH, LOW signal) plus memory address (variable “low”=0). The SB and OP CODE are similar to the BYTE variable READ in the code above, but this variable has an extra 0 (1100). I tested the code with 110 and I get different incoming data. I also thought if BYTE is 8 bits then why not make the BYTE variable READ 11000000, but it changes the incoming data. So now I don't really know how exactly to send SB 1 and OP CODE 10. Need help with that.

Also, as you can see I'm printing the variable "low" and the variable "incoming" (in Binary and Hex) on one line, I thought it would be printing 1 bit per line, but it prints varying amounts of bits. Sometimes it would print 4 bits, 6 bits, or 8 bits, as in 1110, 11111111, 111100. I thought the line `byte incoming = shiftIn(DATA_IN,CLOCK,MSBFIRST);` would get filled with 8 bits all the time, so when I Serial.print() it would have 8 bits, but it's not happening, why?

Also I thought the shifting in of the bits into the variable "incoming" occurs once in the for loop, or is there an inner loop in shiftIn()? I ask because I first made the for loop go for i=\<4095, since there are 4096 bits in this EEPROM, but the increment of I doesn’t match the amount of bits I’m getting on each Serial.print() line. i.e. I would get something like this:

```
1   10111111    BF

```

I thought it would be getting something like this. (I’m thinking the shiftIn() of the 1st bit at address 0 happens when i=0, then 2nd bits gets shiftIn() when i=1, and so forth)

```
1   1
2   1
3   0
4   1
Etc, etc

```

How is shiftIn() shiftinf in the bits into the BYTE variable?

Thanks and sorry if it’s so many questions.

# Answer
> 2 votes
OK I know this is a little late, but for other readers having the same problem, here's a sketch I wrote to read a 93c46 when I had to dump the EEPROM from a car radio. I've deliberately not included the EWEN instruction anywhere as the last thing I wanted to do was accidentally write to the EEPROM.

The key is the modified shiftOut routine which adds a parameter specifying how many bits you want to shift out.

To adapt sketch for other 93c packages, change the number of 16bit words at start of loop{} and number of address bits in 2nd call to myshiftOut.

If your package has an ORG pin, tie it to Vcc.

Hope this helps someone...

```
/*
Arduino Uno sketch to dump a 93c46 EEPROM in 16 bit mode.  Metalbanana 12/9/16, with thanks to raint.
Easily modified for other 93c series parts. Note many 93c46 from autos are 'rotated' pinout,
i.e. those with a T following part no. e.g. 'TEM8':

1=NC    8=ORG
2=Vcc   7=GND
3=CS    6=DO
4=SK    5=DI

so check pcb for Vcc and GND locations with a meter first! An Arduino ProtoShield is ideal to mount IC
as it has a SOIC pad (Note: you can't use the mini breadboard at same time as it covers one set of headers).
Standard shiftOut is not suitable as it sends 8 bits, our addresses are 6 bits,
instructions are 3 bits so sketch uses a modified shiftOut called myshiftOut.
*/

// define pins for eeprom
const int CHIP_SEL = 8;  // to CS
const int CLOCK = 9;     // to SK
const int DATA_IN = 10;  // to DO
const int DATA_OUT = 11; // to DI

const byte READ  = B110;                //read instruction

bool debug = 0;

void myshiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val, uint8_t bits)
{
  for (int i = 0; i < bits; i++)  {
    if (bitOrder == LSBFIRST) {
      digitalWrite(dataPin, !!(val & (1 << i)));
      if (debug)Serial.print(!!(val & (1 << i)));
    }
    else
    {
      digitalWrite(dataPin, !!(val & (1 << (bits - 1 - i))));
      if (debug)Serial.print(!!(val & (1 << (bits - 1 - i))));
    }
    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);
  }
}

void setup() {
  pinMode(CHIP_SEL, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(DATA_OUT, OUTPUT);
  pinMode(DATA_IN, INPUT_PULLUP);

  Serial.begin(9600);
  Serial.println("\n\n");
}

void loop()
{
  for (int addr = 0; addr < 64; addr++) // 64 words for 93c46
  {
    // print address at start of each line
    if (addr % 8 == 0) {
      Serial.println();
      if (addr < 8) Serial.print("0");
      Serial.print(addr * 2, HEX);
      Serial.print(": ");
    }

    digitalWrite(CHIP_SEL, HIGH);
    myshiftOut(DATA_OUT, CLOCK, MSBFIRST, READ, 3); //send READ instruction
    myshiftOut(DATA_OUT, CLOCK, MSBFIRST, addr, 6); //send address, 6 bits for 93c46

    digitalWrite(CLOCK, LOW); // recommended in language reference
    byte incomingH = shiftIn(DATA_IN, CLOCK, MSBFIRST); //receive high byte
    byte incomingL = shiftIn(DATA_IN, CLOCK, MSBFIRST); //receive low byte

    // reverse byte order & print
    if (incomingL < 16) Serial.print("0");
    Serial.print(incomingL, HEX);
    Serial.print(" ");
    if (incomingH < 16) Serial.print("0");
    Serial.print(incomingH, HEX);
    Serial.print(" ");

    digitalWrite(CHIP_SEL, LOW);
  }

  while (1);
}

```

---
Tags: spi, eeprom
---


# Question
Title: using an ESP8266 shield on my Arduino Uno R3 with an unofficial library
I'm using the following Makefile: https://github.com/sudar/Arduino-Makefile It works very well and I was able to get my LED to blink.

Now I bought a WiFi Shield which is NOT supported officially by the Arduino WiFi library. It is the following one I bought: **ESP8266 ESP-12E CC3000 UART WIFI Wireless Shield Board Modul für Arduino UNO R3** \- you can find this on ebay: http://www.ebay.de/itm/262525969091?\_trksid=p2060353.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

What I now am about to do is to include the open source library for the ESP8266 which you can find here: https://github.com/esp8266/Arduino#documentation

Now when I try to upload my sketch it tells me that certain dependencies are not resolved. Like this one here `#include <functional>` which I was not able to include manually. My main problem here is that the github page of the ESP8266 library isn't providing enough information for me how I can get the working lib to use in my sketch. I need to know how I can get this library to work in my sketch!

# Answer
That is **not** a library for the Arduino. That is a **core** for programming the ESP8266 directly as if it were an Arduino itself.
> 2 votes

---
Tags: arduino-uno, esp8266, wifi
---


title: 9V Vin powered Mega - 3V instead of 5V

text:
# Question
Title: 9V Vin powered Mega - 3V instead of 5V
I'm experiencing an issue with an Arduino Mega 2560 : I powered the board through the Vin using a +24 --\> 9V voltage regulator. When I power the board and measure the 5V output from the board, the voltage quickly drops from 5 to ~3V within seconds.

However, while powering with USB, the 5V output from the board gives us a clear 4.8V.

I have checked the 9V Voltage regulator (connected to the Vin), and it has a +24V input which remains stable (as should the 9V).

Any thoughts ?

# Answer
So, according to the comments the main problem should be a thermal protection in `LM7809C` regulator.

The voltage drop between regulator's input and output is about `15 Volts` and even with current consumption about `150mA` it means `2.25W` of power dissipation on it.

For such a big difference between input and output voltage switching regulator is recommended. (Or 9V power supply instead of 24V)

And it is not possible to have `2mA` current consumption. I've just measured power consumption of bare `Arduino Mega 2560` and it is `81mA` through barrel jack input (`9V`) without anything on it. Not even blinking Led. So if you've measured for example `0.2A` it's not `2mA` but `200mA`
> 1 votes

---
Tags: arduino-mega, power, usb, voltage-level
---


# Question
Title: EEPROM bytes preset to 255 while programming
I'm working on a program with Arduino Uno which involves writing and reading EEPROM. I'm using a basic EEPROM library. My problem is: EEPROM values are preset to 255 whenever I burn my program. And there is nothing in my code which will write 255 in these bytes.

I even tried `EEPROM_read` example from the EEPROM library and got same result. I used `EEPROM_clear` code before `EEPROM_read` to set all values to 0. But when I read those values using `EEPROM_read`, they are 255.

Please help explain what is happening.

# Answer
In flash and eeprom memory an erased value is 255. It's all about how flash memory works. If you want something other than 255 in there you will have to write something other than 255 in there.
> 9 votes

# Answer
**You need to set EESAVE fuse**

When the ATmega chip is programmed the memory is erased just before the new code is uploaded. Under normal circumstances the eeprom memory is erased as well as the program memory. The EESAVE fuse can be used to tell the chip not to erase the eeprom. This is useful when you want to upgrade code but keep user settings that are stored in eeprom.

The default value is EESAVE=1, not set and eeprom memory is erased during the chip erase cycle when programming.

This fuse calculator is quite handy.
> 4 votes

---
Tags: arduino-uno, eeprom
---


title: External 5V Power and USB Serial

text:
# Question
Title: External 5V Power and USB Serial
I have a Chinese Arduino nano clone, but I don't know if it's possible to connect the Arduino to external (5v) power and have a USB serial connection ongoing. I'm trying to make a PC controlled LED Strip that can also work on its own.

For example: the PC controls the Arduino sets it to a specific mode and I turn off the PC, but the Arduino should still be running even when the PC is turned off.

I'm new to the world of arduinos.

I'm planning to use this to control addressable LED RGB Strips and am planning to use a 4000mA max power supply.

# Answer
> 7 votes
Having used counterless Arduinos and clones, I can tell you that you can connect both without worrying about any danger. Unless you have a very faulty board, your pc won't be damaged, almost surely neither will the board, as is should select the most powerful source, between your usb or a battery/external PS, while leaving untouched the serial line.

# Answer
> 2 votes
If you are new to something, you should start with reading manual.

Here's what official Wiki page of arduino nano says: https://www.arduino.cc/en/Main/ArduinoBoardNano

> Power:
>
> The Arduino Nano can be powered via the Mini-B USB connection, 6-20V unregulated external power supply (pin 30), or 5V regulated external power supply (pin 27). The power source is automatically selected to the highest voltage source.

# Answer
> 1 votes
The info about 100/150mA USB capability in PC is incorrect. Any normal (not "low-power embedded") USB host must supply 500mA (for USB2.0 ports) and 900mA for USB3.0 ports. In a typical PC this power comes from standby +5VSB rail from system Power Supply. Power rating for this rail is no less than 2A for AT12 compliant PC. Of course it is not advisable to take all this power from one port, due to contact rating limits, and possible polyswitch overcurrent protection of USB ports.

Therefore, if the attached USB device draws total less than 1-1.5A, the design should work fine even if PC is in standby mode (turned off but still connected to AC outlet).

However it is still preferable to use a stand-alone power for this kind of projects. The Arduino board must be designed in a way that, if connected to external higher-voltage source, it would not backdrive any significant current into USB VBUS pin. Usually it gets accomplished by means of one single Schottky diode between VBUS and internal power rail on Arduino board.

You can check if your Arduino drives anything back: power the Arduino with, say, 12V power supply, and check with a Multimeter if VBUS pin on the (unattached) USB connector has any voltage. You should load the VBUS with 10k-15k resistor, and the voltage should be small, 200mV or less, if I remember correctly.

ADDENDUM1: Just checked with Arduino-nano schematics. Yes, there is a "auto selecting" Schottky diode, so there will be no backvoltage on VBUS. However, the Arduino design violates another USB requirement - no signal on any connector pin when VBUS is inactive (low). In the Arduino-nano the VBUS does not control the state of FT232 bridge, so it will always pull-up D+ (USBDP) line as soon as 5V is applied, which is in violation of specs. The side effect of this back-driving is that your PC might not re-connect with the Arduino after waking-up, although it is a rare case these days.

# Answer
> 0 votes
You can connect the Arduino nano to recommended external power supply i.e 5V when it acts as a standalone device with other circuitry. As it is connected to PC it starts drawing power from PC(as PC is acting as a host here) and at the same time serial communication goes on. Now if you want to simultaneously connect the nano to PC or any other host say tablet and external power supply it is recommended that you go for an OTG cable cum power splitter y-cable.

But do not rely on power from PC if you have many sensors or components interfaced to aduino nano as PC is capable of giving max current 100mA in USB 2.0 and approx 150mA in USB 3.0

---
Tags: usb, serial
---


# Question
Title: Cheapest and easiest Arduino board for 12 bit ADC, thinking of M0
I need an Arduino board for simple ADC, but 10 bits of resolution is sadly not enough. I am going to buy a board with 12 bits of resolution, but really couldnt decide on the exact model. It needs to be easily accessable and wont be used for anything else other then ADC. I have my eye on MO, but cant decide if i should buy the pro or the normal one, or just another Arduino board.

I take the data through USB port and the instrument will also be powered with the same USB cable.

*** My only option is to use an Arduino\***

I know i can use the Aref pin or do oversampling but i really am not intrested in those options. thanks for your input

# Answer
> 0 votes
The statement **my only option is to use an Arduino** is not unambiguous whatsoever.

If you meant *"Compatible with Arduino IDE"* than the Teensy 3.2, officially priced on the Arduino store at 17.90 EUR + VAT is the cheapest official Arduino board providing a 12 bit ADC.

If you meant *"Branded as an Arduino"* then the Arduino/Genuino M0 ~~Zero~~, officially priced at 22.00 ~~42.90~~ EUR + VAT is the cheapest board providing a 12 bit ADC.

This is the result of a quick search on the Arduino web site, which you could have checked yourself.

In my opinion the cheapest *"Arduino based"* solution would be an Arduino Pro Mini (officially discontinued) or a barebone ATmega328P along with an external 12 bit ADC. This opens up for many options, just use a parametric search on DigiKey, Octopart or any other website of your choice.

A quick search ended up with MAX1245ACAP priced at 1.30 USD + VAT, probably ending in a BOM cost for the entire solution below 10 USD + VAT, excluding the PCB.

**UPDATE:** as stated in the comments, the `M0` is a cheaper version of the `Zero`.

# Answer
> 3 votes
Use a Teensy 3.x. Those have 13 bit ADCs

---
Tags: analogread, adc, analogreadresolution
---


title: Arduino Parse data serially on VB

text:
# Question
Title: Arduino Parse data serially on VB
I am working with Arduino Uno, I have tracker application running on Arduino Uno board. I am sending data in comma separated value. Now I want to view data into Visual Basic. I have code as below. The below code is working with fake values but as soon it live stream data split functions gives out error.

Serial output data looks like this.

```
Start,Latitude:13.00,longitude:60.00,MODE:1,DIR:1,Local Date:0/0/0,Local Time:5:30:2,tracker_des_angle:0.00,tracker_actual_pos:57.22,Wind Speed :0.00,END
Start,Latitude:13.00,longitude:60.00,MODE:1,DIR:1,Local Date:0/0/0,Local Time:5:30:4,tracker_des_angle:43.00,tracker_actual_pos:69.20,Wind Speed :0.95,END
Start,Latitude:13.00,longitude:60.00,MODE:1,DIR:0,Local Date:0/0/0,Local Time:5:30:6,tracker_des_angle:43.00,tracker_actual_pos:16.34,Wind Speed :1.85,END
Start,Latitude:13.00,longitude:60.00,MODE:1,DIR:0,Local Date:0/0/0,Local Time:5:30:8,tracker_des_angle:43.00,tracker_actual_pos:11.89,Wind Speed :2.77,END

```

visual basic code:

```
Option Explicit On

Imports System
Imports System.IO.Ports
Imports System.Text

Public Class Solar_Track
    Dim comPORT As String
    Dim receivedData As String = ""
    Dim strArray() As String
    Dim Data As String
    Dim latitude() As String
    Dim longitude() As String
    Dim Local_date() As String
    Dim Local_Time() As String
    Dim Mode_oper() As String
    Dim Dir_motor() As String
    Dim Act_pos() As String
    Dim Dis_pos() As String
    Dim wind_pos() As String
    Dim start As Boolean
    Dim End_Result As Boolean
    Dim result As Boolean

    Sub Parse_receivedata(ByVal msg As String)

        RichTextBox1.Text &= msg
        Data = msg

        strArray = Split(Data, ",")
        latitude = Split(strArray(1), ":")
        Text_Latitude.Text = latitude(1)

        longitude = Split(strArray(2), ":")
        Text_Longitude.Text = longitude(1)

        Mode_oper = Split(strArray(3), ":")
        Text_Mode.Text = Mode_oper(1)

        Dir_motor = Split(strArray(4), ":")
        Text_MotorDir.Text = Dir_motor(1)

        Local_date = Split(strArray(5), ":")
        Text_LocalDate.Text = Local_date(1)

        Local_Time = Split(strArray(6), ":")
        Label_hour.Text = Local_Time(1)
        Label_min.Text = Local_Time(2)
        Label_Sec.Text = Local_Time(3)

        Dis_pos = Split(strArray(7), ":")
        Text_TrackerDesire.Text = Dis_pos(1)

        Act_pos = Split(strArray(8), ":")
        Text_TrackerActual.Text = Act_pos(1)

        wind_pos = Split(strArray(9), ":")
        Text_Windspeed.Text = wind_pos(1)

    End Sub

    Sub data_parse()
        Data = "Start,Latitude:13.00,longitude:60.00,MODE:1,DIR:1,Local Date:0/0/0,Local Time:5:30:2,tracker_des_angle:0.00,tracker_actual_pos:54.48,Wind Speed :0.00,END"
        strArray = Split(Data, ",")

        latitude = Split(strArray(1), ":")
        Text_Latitude.Text = latitude(1)

        longitude = Split(strArray(2), ":")
        Text_Longitude.Text = longitude(1)

        Mode_oper = Split(strArray(3), ":")
        Text_Mode.Text = Mode_oper(1)

        Dir_motor = Split(strArray(4), ":")
        Text_MotorDir.Text = Dir_motor(1)

        Local_date = Split(strArray(5), ":")
        Text_LocalDate.Text = Local_date(1)

        Local_Time = Split(strArray(6), ":")
        Label_hour.Text = Local_Time(1)
        Label_min.Text = Local_Time(2)
        Label_Sec.Text = Local_Time(3)

        Dis_pos = Split(strArray(7), ":")
        Text_TrackerDesire.Text = Dis_pos(1)

        Act_pos = Split(strArray(8), ":")
        Text_TrackerActual.Text = Act_pos(1)

        wind_pos = Split(strArray(9), ":")
        Text_Windspeed.Text = wind_pos(1)

    End Sub

    Private Sub Solar_Track_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Enabled = False
        comPORT = ""
        For Each sp As String In My.Computer.Ports.SerialPortNames
            comPort_ComboBox.Items.Add(sp)
        Next
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comPort_ComboBox.SelectedIndexChanged
        If (comPort_ComboBox.SelectedItem <> "") Then
            comPORT = comPort_ComboBox.SelectedItem
        End If
    End Sub

    Private Sub BtConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles connect_BTN.Click
        If (connect_BTN.Text = "Connect") Then
            If (comPORT <> "") Then
                SerialPort1.Close()
                SerialPort1.PortName = comPORT
                SerialPort1.BaudRate = 9600
                SerialPort1.DataBits = 8
                SerialPort1.Parity = Parity.None
                SerialPort1.StopBits = StopBits.One
                SerialPort1.Handshake = Handshake.None
                SerialPort1.Encoding = System.Text.Encoding.Default
                SerialPort1.ReadTimeout = 10000

                SerialPort1.Open()
                connect_BTN.Text = "Dis-connect"
                Timer1.Enabled = True
                Timer_LBL.Text = "Timer: ON"

            Else
                MsgBox("Select a COM port first")
            End If
        Else
            SerialPort1.Close()
            connect_BTN.Text = "Connect"
            Timer1.Enabled = False
            Timer_LBL.Text = "Timer: OFF"
        End If

    End Sub
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        receivedData = ReceiveSerialData()
        ''RichTextBox1.Text &= receivedData
        Parse_receivedata(receivedData)
        receivedData = ""
        '' data_parse()
    End Sub
    Function ReceiveSerialData() As String
        Dim Incoming As String
        Try
            Incoming = SerialPort1.ReadExisting()
            If Incoming Is Nothing Then
                Return "nothing" & vbCrLf
            Else
                Return Incoming
            End If
        Catch ex As TimeoutException
            Return "Error: Serial Port read timed out."
        End Try

    End Function

    Private Sub BtClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtClear.Click
        RichTextBox1.Text = ""
    End Sub

End Class

```

# Answer
Looks like you are using a timer to regularly read the data from the serial port... I think you'd be better using the `DataReceived()` event of the SerialPort class.

The other thing is that you are just reading whatever data is in the buffer (with `ReadExisting`) if all that is in the buffer is 2 or 3 characters (not a full line) then your `Parse_receivedata()` will not be able to split it based on `,`

You want to keep appending the received data to a StringBuilder (or similar) until you hit a CR/LF and then pass it to the `Parse_receivedata()` function:

Psuedo code would be something like:

```
// class scoped variable
rxData = ""

...
// inside the DataReceived() event
rxData += SerialPort1.ReadExisting()
If (rxData.Contains(Environment.Newline)) Then
  lines = rxData.Split(Environment.NewLine)
  toParse = lines[0]
  rxData = lines[1]
  ParseRxData(toParse)
End If

```
> 0 votes

---
Tags: arduino-uno, serial, visualstudio
---


# Question
Title: tinygps abnormal behaviour with EM408 gps
I have an Arduino Duemilanove and em408.

My code is this:

```
#include <TinyGPS.h>
#include <SoftwareSerial.h>

#define GPS_RX_PIN 2
#define GPS_TX_PIN 3

TinyGPS gps;
SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);

void setup()
{
  Serial.begin(9600);
  ss.begin(4800);
  }

void loop()
{
  while (ss.available())
  {
    char c = byte(ss.read());
    // Here i tried Serial.write(c); and i succesully saw the NMEA data in my serial monitor
    if (gps.encode(c))
    {
      long lat, lon;
     unsigned long fix_age;
    gps.get_position(&lat, &lon, &fix_age);
    if (fix_age == TinyGPS::GPS_INVALID_AGE )
      Serial.println("No fix ever detected!");
    else if (fix_age > 2000)
      Serial.println("Data is getting STALE!");
    else
      Serial.println("Latitude and longitude valid!");

      Serial.print("Lat: ");
      Serial.print(lat);
      Serial.print(" Lon: ");
      Serial.println(lon);

    }
    else Serial.println("No data!");
  }
}

```

My output is this:

```
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
No data!
Latitude and longitude valid!
Lat: 32758239
 Lon: 15637489
No data!
No data!
No data!
No data!
No data!
No data!
No data!

```

And then i continue getting No data! forever...

So...

1. Why does gps.encode() only manage to return true only 1 time? I have gotten the raw data from the gps (the commented code on my code snippet) and it's ok. Why it returns true only one time?
2. Why the longitude/latidude data is like this? As far as i know, this isnt valid, correct?

EDIT: Also tried with TinyGPS++.. but no luck in encoding too...

```
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

#define GPS_RX_PIN 2
#define GPS_TX_PIN 3

TinyGPSPlus gps;
SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);

void setup()
{
  Serial.begin(9600);
  ss.begin(4800);
  }

void loop()
{
  while (ss.available()>0)
  {
    char c = byte(ss.read());
    // Here i tried Serial.write(c); and i succesully saw the NMEA data in my serial monitor
    if (gps.encode(c)) //i previously used if(gps.encode(ss.read())); but no luck then
    {
      Serial.print(F("Location: "));
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();

    }
    else Serial.println("No data!");
  }
}

```

New code:

```
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

#define GPS_RX_PIN 2
#define GPS_TX_PIN 3

TinyGPSPlus gps;
SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);

void setup()
{
  Serial.begin(9600);
  ss.begin(4800);
}

char clat[11];
char clng[11];

void loop()
{
    //if (buttons || tilt) {
    //if (buttons & BUTTON_SELECT) {

        bool isGpsLocationValid = false;
        do
        {
            while (ss.available()>0)
            {
                char c = byte(ss.read());
                if (gps.encode(c)) //i previously used if(gps.encode(ss.read())); but no luck then
                {
                    if (gps.location.isValid())
                    {
                        dtostrf(gps.location.lat(), 11, 6, clat);
                        dtostrf(gps.location.lng(), 11, 6, clng);
                        //send-print
                        //delay (just in case multiple bumps)
                        isGpsLocationValid = true;
                    }
                }
             }
        } while (isGpsLocationValid == false);
        Serial.write(clat);
        Serial.println();
        Serial.write(clng);
       //}
    //}
}

```

EDIT: The newest code i have posted works 100%! So if you have similar problems with that aweful gps, use this!

Apparently, TinyGPS and TinyGPS++ don't work well with this gps. To be precice, there is a problem with the gps.encode(c) function.

So using `if (gps.encode(c))` most of the times returns false, except some rare occasions which returns true and then you can do some processing...

My last code takes care of that problem by checking continuously, using a do...while loop. If `if (gps.location.isValid())` returns true, which means i have valid data, then i do the processing i want and end the do...while loop.

# Answer
The newest code i have posted works 100%! So if you have similar problems with that aweful gps, use this!

Apparently, TinyGPS and TinyGPS++ don't work well with this gps. To be precice, there is a problem with the gps.encode(c) function.

So using `if (gps.encode(c))` most of the times returns false, except some rare occasions which returns true and then you can do some processing...

My last code takes care of that problem by checking continuously, using a do...while loop. If `if (gps.location.isValid())` returns true, which means i have valid data, then i do the processing i want and end the do...while loop.

**NOTE:** This code is for TinyGPS++ library. Same theory will work for TinyGPS too of course...

Here it is:

```
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

#define GPS_RX_PIN 2
#define GPS_TX_PIN 3

TinyGPSPlus gps;
SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);

void setup()
{
  Serial.begin(9600);
  ss.begin(4800);
}

char clat[11];
char clng[11];

void loop()
{
    bool isGpsLocationValid = false;
    do
    {
        while (ss.available()>0)
        {
            char c = byte(ss.read());
            if (gps.encode(c)) //i previously used if(gps.encode(ss.read())); but no luck then
            {
                if (gps.location.isValid())
                {
                    dtostrf(gps.location.lat(), 11, 6, clat);
                    dtostrf(gps.location.lng(), 11, 6, clng);
                    isGpsLocationValid = true;
                }
            }
        }
    } while (isGpsLocationValid == false);
    Serial.write(clat);
    Serial.println();
    Serial.write(clng);
}

```
> 2 votes

# Answer
Thaks very much!!! You have already given me the solution for my problem, I\`ve been trying to get this data for 3 days!! When I was using just the GPS module, it was fine, I could get the data, but when I tried to use GSM module + GPS, I could not get the data from GPS!! U gave me the solution

```
bool isGpsLocationValid = false;
        do
        {
            while (ss.available()>0)
            {
                char c = byte(ss.read());
                if (gps.encode(c)) //i previously used if(gps.encode(ss.read())); but no luck then
                {
                    if (gps.location.isValid())
                    {
                        dtostrf(gps.location.lat(), 11, 6, clat);
                        dtostrf(gps.location.lng(), 11, 6, clng);
                        isGpsLocationValid = true;
                    }
                }
             }
        } while (isGpsLocationValid == false);
        Serial.write(clat);
        Serial.println();
        Serial.write(clng);

```

Congratulations!! Brazilian Hugs for you ; )
> 0 votes

---
Tags: softwareserial, tinygps, arduino-duemilanove
---


# Question
Title: What is the most accurate sensor for detecting ping pong ball?
What is the most accurate proximity sensor for a ping pong ball? I will be using this to calculate 3D positioning of a ping pong ball in flight. I only need to detect the ball within 0-5 feet (basically on one side of ping pong table).

# Answer
I've had some good luck with using the Pixy camera system.

http://www.cmucam.org/projects/cmucam5/wiki

You get a maximum of 50 FPS and can detect and locate different objects based on hue. The library function getBlocks() returns the X and Y center location of each of the objects the camera detects. You teach the camera what hues to recognize as blocks, and adjust the detection thresholds. I use mine in monochrome infrared light by adding a visible filter and lens kit from http://irlock.com/
> 1 votes

# Answer
In the meantime a student has made a really impressive implementation, that might answer your question: interactive tennis table
> 0 votes

---
Tags: sensors, proximity
---


title: Accelerometer sample code

text:
# Question
Title: Accelerometer sample code
Just to illustrate my work here, I found a tutorial on how to code an accelerometer, I wanted to understand how does it work, literally get how it works, and not simply using the code without understanding it.

In the beginning of the program,there's a char variable declared as :

`char values[10];`

then later on the code, there was couple lines of getting the information stored in this variable, I'll give this as as example :

`x = ((int)values[1]<<8)|(int)values[0];`

we want X to receive `values[0]` and `values[1]` , that's what that line does up there.

My question is : can someone explain to me how does that line work, and why can't we simply write it as `x = ((int)values[1])|(int)values[0];` ?

# Answer
To understand this you have to start thinking in binary.

The `|` operator is "Perform a binary OR on these two values".

The `<<8` is "Shift this value 8 bits to the left".

If you have two 8-bit values, say (in hex) 0x37 and 0x42, and you OR them together you get:

```
0x37 = 00110111
0x42 = 01000010
--------------- |
0x77 = 01110111

```

In each column where there is a 1 in either value you get a 1 in the result.

Now if you shift the first number 8 bits to the left, you end up with:

```
0x3700 = 0011011100000000
0x0042 =         01000010
------------------------- |
0x3742 = 0011011101000010

```

You do this when a 16-bit value has been split into two 8-bit values and you want to join them back together again into the original 16-bit value.
> 3 votes

# Answer
> up in the beginning of the program, there's a char variable declared as: `char values[10];`

This is not a “char variable”, it's an “array of 10 chars”.

> `((int)values[1]<<8)|(int)values[0]`

Majenko's answer perfectly explains the *intent* of the author of the tutorial, but that is not necessarily what the code *actually* does. As it stands, this piece of code is buggy. Or, to say the least, it has a serious portability problem: it will probably work fine on ARM-based boards, but it will fail on AVR-based boards, and on x86.

The reason is that, in C and C++, the type `char` can be either signed or unsigned, depending on the platform. On most platforms, including AVR, it is signed. This implies that, when a `char` is converted to `int`, it undergoes sign extension instead of being just zero padded. To put it graphically, let's assume the sign bit (most significant bit) of `values[0]` is `s`, then:

```
values[0]      =         sxxxxxxx
(int)values[0] = sssssssssxxxxxxx

```

Here I am assuming an AVR (16-bit ints). If the sign bit happens to be zero, this will work as intended. This is the case in Majenko's example. But if we replace 0x42 with 0xa2, we will have:

```
values[1]         =   0x37 =         00110111
(int)values[1]    = 0x0037 = 0000000000110111
(int)values[1]<<8 = 0x3700 = 0011011100000000
values[0]         =   0xa2 =         10100010
(int)values[0]    = 0xffa2 = 1111111110100010

```

Then, the bitwise OR gives

```
0x3700 = 0011011100000000
0xffa2 = 1111111110100010
------------------------- |
0xffa2 = 1111111110100010

```

and the data in `values[1]` is lost.

**Conclusion**: `values` should be declared as an array of **unsigned** chars, as this will enforce zero-padding instead of sign extension. Always use unsigned types when doing bit manipulations. And you probably should find a better tutorial to learn this kind of stuff.
> 1 votes

---
Tags: accelerometer
---


title: Communicate with ESP8266 RX/TX

text:
# Question
Title: Communicate with ESP8266 RX/TX
I just managed to get a unofficial Arduino WiFi shield to work. But the ESP is flashed on its own now - providing only information to the USB-\>TTL converter and therefore the output goes straight to the Serial Monitor of the Arduino IDE.

Since the ESP is flashed and should be running now - I should be able to disconnected the USB-\>TTL converter and attach the Arduino RX/TX to the ESP TX/RX right?

Then I should receive Serial Data and should be able to process these in my Arduino Sketch right?

So what do I need to do now? Should I start trying a Serial read from the arduino with the baud rate specified by the ESP Flash (11520)? Or do I have to consider something else as well?

# Answer
Your analysis is indeed correct, you can communicate between Arduino and ESP using the serial protocol.

Electrically speaking you must ensure the `RX` and `TX` pins are *crossed*:

`Arduino RX` goes into `ESP TX`
`Arduino TX` goes into `ESP RX`

Also, the two devices **MUST** have a *common ground*, the `GND` pins of the Arduino and the ESP8266 must be tied together.

You don't need level shifters because, even if the ESP8266 runs at 3.3V, its IO ports are 5V tolerant.

Also, as you already pointed out, the two devices must set the same speed (aka BAUD rate) in order to comprehend each other.

In case you decide to transmit binary data please also consider the two devices use a different architecture: Arduino is 8bit, ESP8266 is 32bit, meaning they have different *word size* (the minimum allocation unit size).

I had to face the word size issue when I first tried to exchange a `struct` between an Arduino and a RaspberryPI (also 32bit)...
> 1 votes

---
Tags: arduino-uno, esp8266
---


# Question
Title: Connecting an optris to an arduino uno to send and receive hex strings
I have an optris CT IR sensor, data sheet below.

Is it possible to connect the Uno to the sensor, so I can send a hex string (01) and hopefully receive a hex string from the sensor (04 D3)?

https://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0ahUKEwirjO3oxo7PAhVKDsAKHcjGAcMQFggvMAE&url=http%3A%2F%2Fwww.optris.com%2Foptris-ct-lt%3Ffile%3Dtl\_files%2Fpdf%2FDownloads%2FCompact%2520Series%2FData%2520Sheet%2520optris%2520CT%2520LT.pdf&usg=AFQjCNEb-UKhxvfBE7k7k8zOgEZE9TOJbg&cad=rja

Commands below: (Go to examples section for 01, 04 D3) https://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cad=rja&uact=8&ved=0ahUKEwiM6\_zAx47PAhXoIcAKHVdUCo8QFggoMAI&url=http%3A%2F%2Fwww.optris.co.uk%2Finterfaces%3Ffile%3Dtl\_files%2Fdownloads%2FManuals%2Faddendums-de-en%2Fct-ctlaser-commands.pdf&usg=AFQjCNEkEtwUoiM6jsJYOnGD4-8Yo2Cprg&bvm=bv.132653024,d.ZGg

Thanks

# Answer
> 1 votes
Yes, there are interface options that are compatible with the Arduino. You just have to ensure that you choose the right model so you have the right interface available. Options include RS-232 (with a MAX232 adapter), RS-485 (with a suitable RS-485 shield), CAN (with a suitable CAN shield), Ethernet (with a suitable Ehernet shield) and maybe even the USB version (with the USB Host shield), though the latter is less likely to work.

Pick one that suits your needs best.

---
Tags: arduino-uno, serial, ir
---