Results 1 to 3 of 3
  1. #1
    300+ Forum Addict
    Join Date
    Apr 2008
    Location
    Graham, WA
    Posts
    323
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Driving incandescent lamps with an Arduino & a Centipede shield.

    First, the video!
    http://www.youtube.com/watch?v=o7tJaJJbRkc

    A regular Arduino really drive things that have high power requirements or need a voltage higher than 5vdc. In order to run the real displays in the F-15 that use incandescent bulbs, I developed a special board that would allow me to drive up to 16 channels per board, up to 60vdc at round 8A per board.

    The Centipede Shield by Macetech provides 64 I/O channels - each of the 64 channels can be configured for input or output. In this context however, I'm using the board as strictly an output device.

    Here's the code that the Arduino runs:

    Code:
    /* Centipede Power Driver Interface for the 16 Channel digital output board.
     * Copyright 2012 by Gene Buckle 
     * All Rights Reserved
     * This software is provided as-is and is licensed under the
     * Creative Commons Attribution Share Alike license.  
     * Please see http://creativecommons.org/about/licenses/ for details.
     *
     * I can be reached at geneb@deltasoft.com
     *
     * History:
     * -----------------
     * 18Mar10 gwb Started.
     * 21Jul10 gwb First version!
     * 30Jul10 gwb First publicly releasable version.
     * 21Mar12 gwb Updated to drive the Centipede board instead of the older Gazoutta 16 board.
     *             Provides up to 128 output channels instead of 16.
     *             Board addressing code removed.  Only the Gazatta 16 board required it.
     *
     */
    
    #include 
    #include 
    
    #define CEN_COUNT 1   // # of Centipede boards we have to talk to.
    #define BANK_A    0   // Outputs 0..15
    #define BANK_B    1   // Outputs 16..31
    #define BANK_C    2   // Outputs 32..47
    #define BANK_D    3   // Outputs 48..63
    #define BANK_E    4   // Outputs 0..15 on 2nd addressable Centipede  (64..79)
    #define BANK_F    5   // Outputs 16..31 on 2nd addressable Centipede (80..95)
    #define BANK_G    6   // Outputs 32..47 on 2nd addressable Centipede (96..111)
    #define BANK_H    7   // Outputs 48..63 on 2nd addressable Centipede (112..127)
    
    byte channels[] = {  // Channel map for the Centipede (0..63 for board #1, 64..127 for board #2)
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
        16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
        32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
        48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
        64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
        80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
        96,97,98,99,100,101,102,103,104,105,106,107,108,
        109,110,111,112,113,114,115,116,117,118,119,120,
        121,122,123,124,125,126,127};
    
    
    #define BUF_SIZE  32
    
    int buffer[128];
    int bufIndex = 0;
    Centipede CS;  // create Centipede object...
    
    void setup() {
        int x = 0;
        //Serial.begin(115200);  // Use this baud rate if your host can't use the faster rate below.
        Serial.begin(250000);  // The 250k baud rate gives us a 0% error rate with a 16Mhz clock.
        Wire.begin();
        CS.initialize();
        // Initialize all the channels to be outputs and make sure they're all turned off.
    
        for(x=BANK_A; x < BANK_D+1; x++) {
            if(CEN_COUNT == 1) {
                CS.portMode(x, 0b0000000000000000);
            } 
            else if(CEN_COUNT == 2) {
                CS.portMode(x, 0b0000000000000000);
                CS.portMode(x+BANK_E, 0b0000000000000000);
            }
        }
        for(x = 0;x < BUF_SIZE; x++) {
            buffer[x] = 0;
        }
    }
    
    void loop() {
        int inByte = 0;
        int test = 0;
        if (Serial.available() > 0) {
            /* append the byte to the buffer */
            inByte = Serial.read();
            buffer[bufIndex] = inByte;
            bufIndex++;
            if ((inByte == '*') || (inByte == '\n')) {
                processBuffer();
                clearBuffer();
                bufIndex = 0;
            }
        }
    }
    
    void clearBuffer() {
        int x = 0;
    
        for(x = 0;x < BUF_SIZE; x++) {
            buffer[x] = 0;
        }
    }  
    
    void processBuffer() {
        int cnt = 0;
        int chanBank = 0;
        int chanset1 = 0;
        int chanset2 = 0;
        int cmd = -1;
    
        // Byte 1 is the function byte.  It tells us what we're going to do.
        // 0x00 - Set channels to follow bit state in channel bytes
        // 0x01 - Turn specific channels on
        // 0x02 - Turn specific channels off
        // 0x03 - Turn ALL channels on
        // 0x04 - Turn ALL channels off.
    
        cmd = buffer[0];
        chanBank = buffer[1];  // What bank are we talking to?  0..7 (A..H)
        chanset1 = buffer[2];  // first 8 channels  - binary encoded
        chanset2 = buffer[3];  // second 8 channels - binary encoded
        switch(cmd) {
            case 0x00:
                for (cnt = 0; cnt < 8; cnt++) {
                    if (chanset1 & (1 << cnt)) {
                        CS.digitalWrite(channels[cnt+chanBank], HIGH);
                    } 
                    else
                        CS.digitalWrite(channels[chanBank+cnt], LOW);
                    if (chanset2 & (1 << cnt)) 
                        CS.digitalWrite(channels[chanBank+cnt+8], HIGH);
                    else
                        CS.digitalWrite(channels[chanBank+cnt+8], LOW);
                }
                break;
            case 0x01:
                    for (cnt = 0; cnt < 8; cnt++) {
                        if (chanset1 & (1 << cnt)) {
                            CS.digitalWrite(channels[cnt+chanBank], HIGH);
                        }
                        if (chanset2 & (1 << cnt)) {
                            CS.digitalWrite(channels[cnt+8+chanBank], HIGH);
                        }
                    }
                    break;
            case 0x02:
                    for (cnt = 0; cnt < 8; cnt++) {
                        if (chanset1 & (1 << cnt)) 
                            CS.digitalWrite(channels[cnt+chanBank], LOW);
                        if (chanset2 & (1 << cnt))
                            CS.digitalWrite(channels[cnt+8+chanBank], LOW);
                    }
                    break;
            case 0x03:
                    if (cmd == 0x03) {
                        allChannelsOn();
                    }
                    break;
            case 0x04:
                    if (cmd == 0x04) {
                        allChannelsOff();
                    }
                    break;
        }
    
        //
        //    if (cmd == 'i' || buffer[0] == 'I') {
        //        Serial.println("Centipede Power Driver v1.0");
        //    }
    
    }
    
    void allChannelsOn() {
        int x;
        for(x=BANK_A; x < BANK_D+1; x++) {
            if(CEN_COUNT == 1) {
                CS.portWrite(x, 0b1111111111111111);
            } 
            else if(CEN_COUNT == 2) {
                CS.portWrite(x+BANK_E, 0b1111111111111111);
            }
        }
    }
    
    void allChannelsOff() {
        int x;
        for(x=BANK_A; x < BANK_D+1; x++) {
            if(CEN_COUNT == 1) {
                CS.portWrite(x, 0b0000000000000000);
            } 
            else if(CEN_COUNT == 2) {
                CS.portWrite(x+BANK_E, 0b0000000000000000);
            }
        }
    }
    The Centipede shield breaks down it's I/O in four 16 channel connectors. This is why you'll see references to which "bank" to talk to in the code.

    Make sure that you define CEN_COUNT to match the number of Centipedes you're using - if memory serves, the Centipede code will hang if you try to talk to a second shield if it's not installed.

    Questions? Comments? Rocks?

    g.

  2. Thanks wledzian thanked for this post
  3. #2
    500+ This must be a daytime job Jim NZ's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    764
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Driving incandescent lamps with an Arduino & a Centipede shield.

    Great stuff Gene ,,, It's always neat to see what other guys do and how they code the Arduino.

    Thanks for sharing Gene ,,, Jim
    www.jimspage.co.nz/intro.htm
    All this and Liz still loves me ! !

  4. #3
    300+ Forum Addict
    Join Date
    Apr 2008
    Location
    Graham, WA
    Posts
    323
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Driving incandescent lamps with an Arduino & a Centipede shield.

    You're quite welcome! BTW, the code import on the forum engine wiped out the #include lines. They're supposed to read "#include Wire.h" and "#include Centipede.h". Wrap the filenames in greater-than and less-than signs.

    If you talk to your Arduino using the stock VB6 comm control, the highest baud rate you can use is 115,200.

    g.