Mamba Shield Review


Review of Mamba shield for Arduino Uno


ABSTRACT

This document analyzes the Mamba shield for Arduino with several experiments of powerlines communications over DC lines and AC lines. Principally, I’ve tried to guess the baud rate that this product can reach without transmission errors.

INTRODUCTION

Power line communications technology is a way of carrying data on a conductor that can also be used for power transmission. You can use it to pass a control signal through the electrical wiring in a house for home automation. LinkSprite's Mamba shield gives your Arduino this ability. This Narrowband Powerline Communication shield can be controlled by your Arduino board using a simple SPI interface.  This product can be bought in the references [1] and [2]. It is not very expensive, his price is about 50 €. From these places you can download the electric schematic, the codes and a step-by-step guide. The board needs to supply at least 1 Amp to work correctly. One of his inconvenient is that it needs a lot of caution if you use the board with high voltage. 
     
Figure 1: Mamba Shield for Arduino

    
The main element of Mamba shield is the PLM-1 modem. That chip is the brain of the board. It is a fully digital data transceiver for powerline communications using Frequency-Shift Keying (FSK) and it is designed to be controlled from an external Central Processing Unit, most commonly a microcontroller (MCU). Implementing the PHY and MAC layers of the OSI model, the PLM-1 provides a way to efficiently modulate and demodulate data packets. It features collision detection, as well as automatic forward error correction and CRC-16 data integrity verification. For more information, you can read the AC-PLM User manual that it can be downloaded from [3]. After this brief introduction, I explain the tests with this Arduino Shield.

TEST 1: MAMBAS CONNECTED DIRECTLY THEMSELVES

This test consists in sending messages from one PLC emitter to the PLC receiver. The received messages should not have any error. The PLCs are united by couples of wires which they have not an extra direct current, only the signal transmitted by the PLCs. The size of the message, the speed transmission, the loss packet rate and the length of the wires will change for watching the differences of loss packets in the transmissions. The Arduino are powered by the USB connected to the PC. The picture below shows the two Arduino connected directly.
   
Figure 2: Two Mamba Shields joined directly by two wires of 30 cm.



   
This test is for seeing the change of the quantity of loss packet with different baud rates. The transmission code is running always and the loops are separated by a delay of milliseconds. The baud rate will be faster if the delay is less. The codes of the two Arduino with the Mamba shield are provided at the end of this review. The Appendix1 has the transmiter code and the Appendix 2 has the receceiver code.
   
After a study of the code, I’ve reached to the conclusion that the maximum size of the data in a packet is 61 bytes. In each transmission the packet has 3 bytes of header and end of packet that they are configured by the protocol transmission of the Mamba Library. The total size of a packet in a transmission is 64 bytes. The structure of a packet is resumed below.

First nibble
Reserved(0)
Channel
User Data
End of Packet
5 bits
1 byte (0-255)
61 bytes
4 bits (CRC16)
Table 1: Structure of a packet.

The next tables show the relations among the loss packet rate with different delays, size of packet and length of the wires. I’ve selected these delays because they are the points where the loss packet changes in the communications. The Table 2 shows the results with wires of 30 cm and the second Table 3 with wires of 250 cm. The column of characters means the number of bytes of a message without header and end of packets. The size of packet has influence in the loss packet rate. 


Mamba Shield connected by wires of 30cm
61 Characters (The maximum)
32 Characters
5 Characters
Delay (ms)
Loss packet rate (%)
Delay (ms)
Loss packet rate (%)
Delay (ms)
Loss packet rate (%)
260
0
165
0
65
0
257
10
160
10
63
25
256
20
159
25
60
33
255
33
158
33
50
50
250
50
100
50
20
72
100
60
70
60
10
85
50
82
50
75
0
96
20
92
20
88


10
98
10
93


0
99
0
99


 Table 2:  Relations among loss packets rate, delays and size of packets with wire of 30 cm.
    
The data of the Table 2 are plotted in the graph below:
    
Graph 1: data of Table 2. Relations among loss packets rate, delays and size of packets with wire of 30 cm.


    
Now, the results of the same test with wires of 250 cm of length are in the Table 3.

Mamba Shields connected by wires of 250cm
61 Characters (The maximum)
32 Characters
5 Characters
Delay (ms)
Loss packet rate (%)
Delay (ms)
Loss packet rate (%)
Delay (ms)
Loss packet rate (%)
250
0
170
0
65
0
248
12
160
10
60
10
244
33
158
33
59
25
240
50
150
50
58
33
120
60
80
54
55
50
80
75
78
60
30
55
50
80
50
75
20
69
30
89
30
84
15
76
10
95
10
87
10
84
0
99
0
99
0
99

Table 3:  Relations among loss packets rate, delays and size of packets with wire of 250 cm.

The data of the Table 3 are plotted in graph below:

Graph 2 data of Table 3. Relations among loss packets rate, delays and size of packets with wire of 250 cm.




   
The picture of the second experiment with wires of 250cm is shown beneath.
 
Figure 3: Two Mamba shield connected by wire of 250 cm.

























The conclusions of this test are these:
   
-The number of bytes in a packet transmitted has influence in the Speed Transmission Rate because with less number of bytes, the loss packet is less, hence, the delay in the transmitter code can be smaller. 
           
-The length (short distances) of the wire has not influence in the Speed Transmission Rate because the loss packets are similar with wires of 30 cm and 250 cm.

TEST 2: MAMBAS CONNECTED THROUGH A 12V LINE 

This test consist in to send messages from the PLC emitter to the PLC receiver and to capture the message to check if they are received correctly. The connection of the Mamba Shields is made over a 12 V line generated for a power source that it provides 1 Amp to a little computer with a touch screen. The length of the message, the speed transmission and the distance from the emitter to the power source varies to observe the differences in the loss packet transmitted. In this test the Arduinos are powered by the USB cable. The final assembly is showed in the Figure 4 and the scheme of it is in the Figure 5.
 

Figure 4: Assembling of the power source, the touch screen, the Arduinos with the Mamba Shield and the laptop.

Figure 5: Scheme of the assembling of the test 2.



 
The Arduino codes are provided in the Appendix 1 and Appendix 2. The results of the communication are in the Table 4.

PLCs connected to a line with 12V with the emitter far away from the power source and the receptor close
61 Characters (The maximum)
32 Characters
5 Characters
Delay (ms)
Loss packet rate (%)
Delay (ms)
Loss packet rate (%)
Delay (ms)
Loss packet rate  (%)
240
0
160
0
70
0
239
4
157
11
68
13
238
15
156
20
67
25
237
25
155
33
65
33
235
33
150
50
60
50
230
50
60
66
30
66
100
66
50
70
20
75
50
77
30
78
10
84
20
88
20
85
0
99
0
99
0
99


Table 4: Results of the PLCs connected to a line with 12V with the emitter far away from the power source and the receiver close to the power source.

These data are plotted in the following graph.
  
Graph 3: data of Table 4. Relation between the speed transmission rate of Mamba Shield and the loss packet rate over a line of 12V with the emitter close to the power source.




  
Some observations during the test are that if the Arduinos are powered by the electric network, the emitted signal has more power than if the Arduinos would be powered by the USBs of the laptop. This can be watched if we connect an oscilloscope to the outputs wires. In my case, the difference is 1.8 Vpp from the electric network to the 0.5 Vpp from the laptop.
   
One problem found during this test was when a Mamba Shield is transmitting close to the power source, the other Mamba never receives anything. I tried to change the Mambas to know if one of them was broken but I obtained the same results.

The conclusions of this test are these:

-The Speed Transmission reached is the same that the Test 1, 2048 bps. The highest frequency of transmission without loss packets is 4 Hz (1/250 milliseconds) with the delay of 250ms. The calculation is: 8 bits x 64 bytes/packet x 4 Hz = 2048 bits per second.

-External elements affect to the signal of Mamba shield. This reason can be why the Mambas don’t work in the electric network. This case is explained in the next test.
   

TEST 3: MAMBAS IN THE ELECTRIC NETWORK


The Test 3 tries to communicate the two PLCs through the electric network of the laboratory with the aim of getting a bidirectional transmission.  Very important: take cautions to avoid possible accidents with the high voltage of the electric plugs. I have used an empty CD box as case for the Arduino. It is needed to isolate the electric parts to avoid electrical shocks. Furthermore, I’ve changed the wires that are connected to the plugs for manipulating them easily and safe.  The Figure 6 shows the material that I’ve used. I’ve divided this test in 3 parts because depending on the way that the PLCs are connected to the electric network the features of the communication are different.

The wall adaptor used to the transmitter Mamba Shield is shown in the Figure 6.
  
Figure 5: box to cover the Arduino and Mamba Shield and the new electric cable.





Figure 6: Wall adaptor of 1A.
   
TEST 3.1: Mambas directly to the electric network

Both Mamba shields are connected directly to the electric network. This test has been very unsatisfactory because I have not got any communication between them.  I did the same proof at home apart of the laboratory but also I have not had good results. Perhaps it is for the impedance of the electric network or length of the electric cables. I don’t know the cause. For this reason, I’ve carried out other experiments such as the next tests. The following figure shows the scheme of connections.

Figure 7: Mambas connected directly to the electric network.




  

TEST 3.2: Mambas connected to a multiple plug 

In this experiment I’ve connected the two Mamba Shields to a multiple plug connected to the electric network.  If the two boards are loaded with the code example provided by LinkSprite’s, the communication is bidirectional but only for a while because this is broken off with the time.If I load my codes on the Mambas Shields, the communication is unidirectional. They only work if the COM=15 is the transmitter and the COM=13 is the receiver (in the case of my devices). I suspect that one of them does not work properly. However, I think that if I would have more Mamba Shield for testing, this experiment would be bidirectional. The delay used in the code is 260 ms. The transmission is ok but the communication broke off quickly than if I use a higher delay such as one second. In the picture below you can see the assembling of the experiment.
 
Figure 8: Assembling of Test 3.2
To understand better this, I’ve included a schematic of the assembling in the Figure 9.
Figure 9: Scheme of assembling Test 3.2
Maybe, in this test the signal doesn’t travel through the powerlines, only by the internal circuitry of the multiple plug. For this reason, in the next test I use two multiple plug.
             
TEST 3.3: Mambas connected to several multiple plugs 

This time I’ve used two multiple plugs to ensure that the signal travel along an electric cable. The connections among the devices are showed in the following scheme.

Figure 10: Scheme of assembling of Test 3.3


The next Figure shows a photo of the assembling.
Figure 11: Assembling of Test 3.3






The results of Test 3.3 have been the same as Test 3.2

TEST 4: Mambas connected to the car lighters

This experiment tries to use the powerlines of a car to transmit the signal of the Mamba Shields. In this case, I use two car lighters. I’ve put one Mamba connected to the car lighter of front part and other Mamba connected to the car lighter of the rear part. I have not got any communication between them. I think that the situation of this experiment is like the Test 3.1

Using the two car lighters of the rear part, the communication between the Mambas was ok. This situation is similar to use the multiple plugs of the Test 3.2.

Figure 12: Mamba Shield and the new wire used to the test in the car lighters.



      
CONCLUSIONS OF THE TESTS


  • The highest speed transmission data rate on powerline is around 2048 bytes. This conclusion has been verified by LinkSprite’s. See [4].
  • If the message of the packet has more than 61 bytes, the system doesn’t work and anything is transmitted.

  • The length of a message affects to the loss packet rate.  Fewer bytes in the packets means lower loss  packet rate and as a consequence, higher speed transmission.

  • The Mamba Shields sometimes fail at high speed transmissions (2k) and it is necessary reset it.

  •  With the correct code, you can transmit whatever you want over DC lines at 2048 bps.

  •  The Mamba shields do not work connected directly to the power lines of 220V.


REFERENCE

[1] http://www.linksprite.com/product/showproduct.php?id=69

APPENDIX 1

Example code:
/******************************************************************************************
** LinkSprite Technologies, Inc
* Arduino Powerline Communication Shield Sample Code
*   Jingfeng Liu
*   jingfeng.liu@linksprite.com
*   8/19/2011
 ******************************************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <arduino.h>

#include "spi.h"
#include "ports.h"
#include "plm1.h"

#define MOSI            B,3
#define MISO            B,4
#define SCK             B,5


static volatile bool uart_tx_flag = false;      /* Flag for Tx UART interrupt. */
static volatile bool uart_rx_flag = false;      /* Flag for Rx UART interrupt. */
static uint8_t uart_rx_data;                    /* Rx UART data read. */

uint8_t rx_packet[PLM_RX_MAX_PACKET_SIZE];
uint8_t rx_length = 0;
uint8_t tx_packet[PLM_TX_MAX_PACKET_SIZE];
uint8_t tx_length = 0;

uint8_t incomingByte = 0;    // for incoming serial data

void setup()                   
{
   PIN_OUTPUT(MOSI);// MOSI(Master Out Slave In) should be pin 11 in Arduino
   PIN_OUTPUT(SCK);//SCK (Serial Clock ) should be pin 13 in Arduino
   PIN_OUTPUT(nPLM_RESET);// B,0 /* Reset pin. */
   PIN_OUTPUT(PLM_CS);//B,2 /* CS pin. */--->Slave Select should be pin 10 in Arduino
   PIN_INPUT(MISO);//MISO(Master In Slave Out ) should be pin 12 in Arduino

   /* SPI communication must be initialized before plm1 library. */
   spi_init( SPI_SPEED_F16 );

   /* Initialization of plm1 library. */
   plm1_init();

   /* Activate external interrupt 0 for PLM-1 */
   EIFR = 0xFF;                              /* Clear external interrupt flags. */
   EICRA = _BV( ISC00 ) | _BV( ISC01 );      /* INT0 activated on a rising edge. */
   EIMSK = _BV( INT0 );                      /* Enable only external interrupt 0 (PLM). */

   Serial.begin(9600);           // set up Serial library at 9600 bps
   
   /* Activate global interrupts. */
   sei();
    
}

void loop( void )
{
      // send data only when you receive data:
      if (Serial.available() > 0)
      {
                   // read the incoming byte:
                   incomingByte = Serial.read();
           plm1_send_data(&incomingByte, 1);
      }

      /* When a packet is received, plm1_receive returns the length of the
       * packet and copies the contents of the packet in rx_packet. */
      if( (rx_length = plm1_receive(rx_packet)) )
      {
          Serial.println(byte(rx_packet[0]));
      }
}

/* Interrupt Service Routine provenant de la ligne d'interruption du PLM. */
SIGNAL(INT0_vect)
{
   plm1_interrupt();
}


APPENDIX 2

My code for the Tx Mamba:
/******************************************************************************************
** LinkSprite Technologies, Inc
* Arduino Powerline Communication Shield Sample Code
*   Jingfeng Liu
*   jingfeng.liu@linksprite.com
*   8/19/2011
 ******************************************************************************************/
#include <arduino.h>
#include "spi.h"
#include "ports.h"
#include "plm1.h"

#define MOSI            B,3
#define MISO            B,4
#define SCK             B,5

static volatile bool uart_tx_flag = false;      /* Flag for Tx UART interrupt. */
static volatile bool uart_rx_flag = false;      /* Flag for Rx UART interrupt. */
static uint8_t uart_rx_data;                    /* Rx UART data read. */

uint8_t rx_packet[PLM_RX_MAX_PACKET_SIZE];
uint8_t rx_length = 0;
uint8_t tx_packet[PLM_TX_MAX_PACKET_SIZE];
uint8_t tx_length = 0;
uint8_t incomingByte = 0;    // for incoming serial data

char * str_seq = NULL;

uint8_t u_data[63];
uint8_t data_len = 0;
void builtpacket(int num_paquete);

void setup()                   
{
   PIN_OUTPUT(MOSI);// MOSI(Master Out Slave In) should be pin 11 in Arduino
   PIN_OUTPUT(SCK);//SCK (Serial Clock ) should be pin 13 in Arduino
   PIN_OUTPUT(nPLM_RESET);// B,0 /* Reset pin. */
   PIN_OUTPUT(PLM_CS);//B,2 /* CS pin. */--->Slave Select should be pin 10 in Arduino
   PIN_INPUT(MISO);//MISO(Master In Slave Out ) should be pin 12 in Arduino

   /* SPI communication must be initialized before plm1 library. */
   spi_init( SPI_SPEED_F16 );

   /* Initialization of plm1 library. */
   plm1_init();

   /* Activate external interrupt 0 for PLM-1 */
   EIFR = 0xFF;                              /* Clear external interrupt flags. */
   EICRA = _BV( ISC00 ) | _BV( ISC01 );      /* INT0 activated on a rising edge. */
   EIMSK = _BV( INT0 );                      /* Enable only external interrupt 0 (PLM). */

   Serial.begin(9600);           // set up Serial library at 9600 bps
   
   /* Activate global interrupts. */
   sei();  
}

int loops=0,Speed=1000;

void loop()
{     
 
    for(int num_packet=0;num_packet<100;num_packet++)
    {     
       builtpacket(num_packet);
       plm1_send_data(u_data, data_len);    
       delay(Speed);
    }  
    loops++;
    Serial.print("Loops=");Serial.println(loops);
    delay(15000);
   
}

/* Interrupt Service Routine provenant de la ligne d'interruption du PLM. */
SIGNAL(INT0_vect)
{
   plm1_interrupt();
}

void builtpacket(int num_paquete)
{
    //Local Variables
    char * message = NULL;//Message to send
    char paquete[63]; //All the information that it will be sent
    int lengthMessage=52; //The message has 32 bytes by default. This parameter can be modified
    message = (char *)calloc(lengthMessage+1,sizeof(char));
   
    //Build the message to send
    str_seq = NumSeq(num_paquete,4);//The number of the packet has four characters
    strcpy (message,"El numero de caracteres maximo a enviar es de 61");
    //strcpy (message,"El num de max");
    sprintf(paquete,"*%s;Speed: %d;%s#",str_seq,Speed,message);
    //sprintf(paquete,"*%s;%d#",str_seq,Speed); 
    Serial.println(paquete);
   
    //Translate char to uint8
    data_len = strlen(paquete);
    for(uint8_t i=0;i<data_len;i++)
    {
      u_data[i] = (uint8_t)paquete[i];
    }
    free(str_seq);
    free(message);   
}

//  str_seq = NumSeq(1000,4);
char * NumSeq(long value,uint8_t len)
{
                char * str = NULL;
                char * aux = NULL;
                uint8_t i = 0;
                long guarda = 10;
                 
                str = (char *)calloc(len+1,sizeof(char));
               
                if(str == NULL)
                               return NULL;
               
                for(i=1;i<len;i++)
                {
                               if(value < guarda)
                               {
                                               aux = (char *)calloc((len-i)+1,sizeof(char));
                                               memset(aux,0x30,(len-i)); //0x30 es el codigo ascii del 0
                                               sprintf(str,"%s%d",aux,value);
                                               free(aux);
                                               return str;
                               }
                               guarda *= 10;
                }
               
                sprintf(str,"%d",value);
               
                return str;
}
//  free(str_seq);


APPENDIX 3

My code for the Rx Mamba:
/******************************************************************************************
** LinkSprite Technologies, Inc
* Arduino Powerline Communication Shield Sample Code
*   Jingfeng Liu
*   jingfeng.liu@linksprite.com
*   8/19/2011
 ******************************************************************************************/
#include <arduino.h>
#include "spi.h"
#include "ports.h"
#include "plm1.h"

#define MOSI            B,3
#define MISO            B,4
#define SCK             B,5


static volatile bool uart_tx_flag = false;      /* Flag for Tx UART interrupt. */
static volatile bool uart_rx_flag = false;      /* Flag for Rx UART interrupt. */
static uint8_t uart_rx_data;                    /* Rx UART data read. */

uint8_t rx_packet[PLM_RX_MAX_PACKET_SIZE];
uint8_t rx_length = 0;
uint8_t tx_packet[PLM_TX_MAX_PACKET_SIZE];
uint8_t tx_length = 0;

void setup()                   
{
   PIN_OUTPUT(MOSI);
   PIN_OUTPUT(SCK);
   PIN_OUTPUT(nPLM_RESET);
   PIN_OUTPUT(PLM_CS);
   PIN_INPUT(MISO);

   /* SPI communication must be initialized before plm1 library. */
   spi_init( SPI_SPEED_F16 );

   /* Initialization of plm1 library. */
   plm1_init();

   /* Activate external interrupt 0 for PLM-1 */
   EIFR = 0xFF;                              /* Clear external interrupt flags. */
   EICRA = _BV( ISC00 ) | _BV( ISC01 );      /* INT0 activated on a rising edge. */
   EIMSK = _BV( INT0 );                      /* Enable only external interrupt 0 (PLM). */

   Serial.begin(9600);           // set up Serial library at 9600 bps

   /* Activate global interrupts. */
   sei();  
} 

char * data = NULL;
void loop()
{
 if( (rx_length = plm1_receive(rx_packet)) )
   {    
      data = (char *)rx_packet;
      data[rx_length] = '\0';    
      Serial.println(data);
   }
}

/* Interrupt Service Routine provenant de la ligne d'interruption du PLM. */
SIGNAL(INT0_vect)
{
   plm1_interrupt();
}