Hi All,
I posted last week asking for help understanding a library that I thought would help me here...long story short I figured out that the RX side of the library wasn't implemented.
So here is what I'm trying to do, decode DALI (Digitally Addressable Lighting Interface). It is a Manchester encoded signal with 1 Start-bit, 16 data-bits (8 are an address and 8 are actual data), and 2 stop-bits.
I tried several libraries for manchester encoding and found one that would actually output data by Nick Gammon, it is here: Yet another Manchester encoding / decoding library ... - Programming Questions - Arduino Forum
I noticed that I wasn't getting the entire packet, so I made a couple of changes. Basically there is an array that stores any data received and was a "char" type, I changed its type to "word" and did the same for any data types going into/out of the buffer. I have gotten that to work correctly as after making those changes I got the same partial data.
I then found a counter that looks to receive 8 bits, I changed it to 16 bits and it breaks the library. I mean that it compiles but it never outputs any data. As if it never sees all 16 bits or something.
Here is my modified .cpp
// ManchesterInterrupts.cpp
//
//
// Created by Nick Gammon on 22nd January 2012.
#include <ManchesterInterrupts.h>
namespace ManchesterInterrupts {
// variables
// state machine
byte manchesterState = IDLE;
// true if we got the first of the two bits per data bit
boolean gotFirst;
// current data byte
word dataByte;
// how many bits in the data byte we have
byte bitCount;
// how many sync bits we got already
byte zeroCount;
// when last transition occurred
unsigned long lastBitChange;
// what pin the incoming data is on
byte dataPin;
// exported variables
// buffer to hold received bytes
volatile word buf [32];
// position in buffer
volatile word inpoint, outpoint;
// functions
void emitBit (const byte b)
{
// discard the first bit of a pair, the second one is the value
// eg. 01 is 1, 10 is 0
if (manchesterState != IDLE && !gotFirst)
{
gotFirst = true;
return;
} // end of first bit of pair
gotFirst = false;
switch (manchesterState)
{
case IDLE:
if (b == 0)
{
manchesterState = PREAMBLE;
zeroCount = 1;
} // end of got a sync bit
return; // end of IDLE
case PREAMBLE:
if (b == 1)
{
if (zeroCount < MIN_ZEROES)
{
manchesterState = IDLE;
return;
} // end of too few sync bits
manchesterState = DATA;
bitCount = 0;
return;
} // end of a 1 bit
zeroCount++;
return; // end of PREAMBLE
case DATA:
dataByte >>= 1;
if (b)
dataByte |= 0x80;
bitCount++;
if (bitCount == 15)
{
manchesterState = IDLE;
char next = inpoint + 1; // next insert point
// wrap-around at end of buffer
if (next >= sizeof buf)
next = 0;
if (next == outpoint) // caught up with removal point?
return; // give up
// insert at insertion point
buf [inpoint] = dataByte;
inpoint = next; // advance to next
return;
} // end of got all 8 bits
break; // end of DATA
} // end of switch on manchesterState
} // end of ManchesterInterrupts::emitBit
/*
We might get:
10 <-- transition with a single width: emit a 0 bit
01 <-- ditto: emit a 1 bit
001 <-- transition with a double width: emit a 0 bit then a 1 bit
110 <-- ditto: emit a 1 bit then a 0 bit
If the time from the last to this is not either (approximately)
PULSE_WIDTH or DOUBLE_PULSE_WIDTH then it is an error.
*/
// called for an interrupt on the incoming pin
void isr ()
{
byte val = digitalRead (dataPin); // the new data state
unsigned long timeDiff = micros () - lastBitChange;
lastBitChange = micros ();
// single width transition?
if (timeDiff >= LOW_WIDTH && timeDiff <= HIGH_WIDTH)
{
emitBit (val);
return;
} // end of single-width pulse
// single width transition?
if (timeDiff >= DOUBLE_LOW_WIDTH && timeDiff <= DOUBLE_HIGH_WIDTH)
{
emitBit (!val);
emitBit (val);
return;
} // end of double-width pulse
// other is not so good ...
manchesterState = IDLE; // error
} // end of ManchesterInterrupts::isr
int available ()
{
int count = ManchesterInterrupts::inpoint - ManchesterInterrupts::outpoint;
// adjust for wrap-around
if (count < 0)
count += sizeof ManchesterInterrupts::buf;
return count;
} // end of ManchesterInterrupts::available
int read ()
{
// check if any data
if (ManchesterInterrupts::inpoint == ManchesterInterrupts::outpoint)
return -1; // nothing
byte c = ManchesterInterrupts::buf [ManchesterInterrupts::outpoint];
if (++ManchesterInterrupts::outpoint >= sizeof ManchesterInterrupts::buf)
ManchesterInterrupts::outpoint = 0; // wrap around
return c;
} // end of ManchesterInterrupts::read
} // end of namespace ManchesterInterrupts
And the modified .h
//
// ManchesterInterrupts.h
//
//
// Created by Nick Gammon on 22nd January 2012.
#ifndef _ManchesterInterrupts_h
#define _ManchesterInterrupts_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
namespace ManchesterInterrupts {
// constants
// this it the bit rate (data rate is half that as it takes two transitions per data bit)
const unsigned long PULSE_WIDTH = 400; // uS
const int PERCENTAGE_VARIANCE = 10; // how much we tolerate the pulse width being out (max 50)
// if you get 1001 or 0110 that is two pulses widths with no transition
const unsigned long DOUBLE_PULSE_WIDTH = PULSE_WIDTH * 2; // uS
// pulses widths should be within 10% of expected
const unsigned long LOW_WIDTH = PULSE_WIDTH - (PULSE_WIDTH * PERCENTAGE_VARIANCE / 100);
const unsigned long HIGH_WIDTH = PULSE_WIDTH + (PULSE_WIDTH * PERCENTAGE_VARIANCE / 100);
const unsigned long DOUBLE_LOW_WIDTH = DOUBLE_PULSE_WIDTH - (PULSE_WIDTH * PERCENTAGE_VARIANCE / 100);
const unsigned long DOUBLE_HIGH_WIDTH = DOUBLE_PULSE_WIDTH + (PULSE_WIDTH * PERCENTAGE_VARIANCE / 100);
// a data byte starts with this many zero "sync" bits and then a 1 bit
const byte MIN_ZEROES = 0;
// state machine states
enum { IDLE, PREAMBLE, DATA };
// variables
// state machine
extern byte manchesterState;
// true if we got the first of the two bits per data bit
extern boolean gotFirst;
// current data byte
extern word dataByte;
// how many bits in the data byte we have
extern byte bitCount;
// how many sync bits we got already
extern byte zeroCount;
// when last transition occurred
extern unsigned long lastBitChange;
// what pin the incoming data is on
extern byte dataPin;
// exported variables
// buffer to hold received bytes
extern volatile word buf [32];
// position in buffer
extern volatile word inpoint, outpoint;
// functions
void isr ();
int available ();
int read ();
} // end of namespace ManchesterInterrupts
#endif
Can someone please point out what I missed? To me it really looks like it should work.
Thanks in advance for the help!