DMX receiver (3 channel)

I always wanted to make a decent controller for LED strips, so the most logical choice would be to get started with DMX. On this page I will describe this project of mine.

Step 1: design some PCB’s! Note that the final PCB will be 17*50mm

This morning the mailman delivered a cute box all the way from HongKong! My PCB’s arrived, and I was kind of surprised, see for yourself:

Just so you know: I ordered 10 of those, and i got 22! I even had 8 electrically checked. THANK YOU SEEEDSTUDIO!

These small boards look just great

Not a single remark I can make concerning the quality! The only design flaw (but thats my fault) is an interruption in the ground plane because of a via.

I immediately soldered one of these boards as a testing setup

That is:
PIC12F1822
MAX3485
Microchip 3.3V regulator
BC847B

In the end it will be attached to a smaller piece of an RGB led strip, but for the moment I use it entirely.

I finished developping the software for the microcontrollers *jeej*!

I’m using Freestyler which is a Belgian freeware, so I’m happy to use it. I can control the three colours (Red, Green, Blue) of each strip separately via the (surprisingly easy) DMX protocol.

Enough Jibber Jabber; here are pics!

Each module is connected by a small pinheader (12V, GND, D+ & D-)

DMX receiver module:

Power & terminating resistor module:

USB communication module (without the FTDI232RL breakout board):

I’ll try cleaning up the Assembly code, group schematic, PCB and BOM files and release it here for the public!
There are still ‘some’ PCBs left, so if you’re interested, send me an email (look on top of this website)

So you want to see some code, well here you have it!

In short: It’s in ASM, it uses software PWM (based on a timer interrupt) and the uart hardware firing interrupts.
I wouldn’t call it finished, but it’s in a working state :-) I hope comments explain the entire code, but I must admit that I have to reread my own code to figure out how I did it. If you have any questions, just post a reply (if the bots didn’t break it, otherwise just mail).

#include 
	list p=12f1822, r=dec
;	errorlevel -306 ; no page boundary warnings
;	errorlevel -302 ; no bank 0 warnings
;	errorlevel -202 ; no 'argument out of range' warnings

; LED pin locations
#define PIN_R	0
#define PIN_G	2
#define PIN_B	1

; Defines starting conditions of pins
#define	DUTY_R	0x20
#define	DUTY_G	0xAA
#define	DUTY_B	0xFF

; Defines addresses
#define R_ADDR_LOW  0x07
#define R_ADDR_HIGH 0x00

; Defines addresses
#define G_ADDR_LOW  0x08
#define G_ADDR_HIGH 0x00

; Defines addresses
#define B_ADDR_LOW  0x09
#define B_ADDR_HIGH 0x00

; Defines end address (standard is 512)
#define TOTAL_ADDR_LOW  0x00
#define TOTAL_ADDR_HIGH 0x02

    __config _CONFIG1, (_FCMEN_OFF & _IESO_OFF & _CLKOUTEN_OFF & _BOREN_ON & _CPD_ON & _CP_OFF & _MCLRE_ON & _PWRTE_OFF & _WDTE_OFF & _FOSC_INTOSC) ; 0011 1111 1110 0100
    __config _CONFIG2, (_WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_19 & _LVP_OFF) ; 0001 1110 1111 1111

#define BREAK   0

    cblock 0x70
    teller
    duty_r
    temp_duty_r
    duty_g
    temp_duty_g
    duty_b
    temp_duty_b
    addr_low
    addr_high
    temprc
    stat
    endc

    org 0x000
    nop
    goto	init

    org 0x004
    ;---------------------------------------
    ; Interrupt handler
    ;---------------------------------------
    bcf	INTCON, GIE

    movlb   0
    btfsc   PIR1, RCIF
    goto    serialprocedure

    btfsc   INTCON, TMR0IF
    goto    timerprocedure

serialprocedure
    movlb	3
    ;btfsc       RCSTA, FERR     ; Test for framing error
    ;retfie  ; This is the start sequence

    btfss       RCSTA, FERR     ; Test for framing error
    goto        testandinc
    movf        RCREG, W        ; Mark register as read
    bsf         stat, BREAK     ; Break has passed, set bit
    movlw       0xFE
    movwf       TXREG
    retfie

testandinc
    btfss       stat, BREAK     ; Test if break has happened
    goto        serialinc       ; We're past the start sequence

    ; This is the start byte
    movf        RCREG, W        ; Mark register as read
    bcf         stat, BREAK     ; Clear break bit
    retfie

serialinc
    ; Increment counter
    incf        addr_low, F     ; Increment the Low byte
    btfsc       STATUS, Z       ; Do we have Zero (Multiple of 256)?
    incf        addr_high, F    ; Increment High byte (if necessary)

    movf        RCREG, W        ; Move RCREG in a private variable
    movwf       temprc

    call        debugger

testRedAddress
    movlw	R_ADDR_LOW
    subwf	addr_low, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testGreenAddress
    movlw	R_ADDR_HIGH
    subwf	addr_high, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testGreenAddress
    ; If this is reached, address is the same
    movf        temprc, W
    movwf       temp_duty_r

testGreenAddress
    movlw	G_ADDR_LOW
    subwf	addr_low, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testBlueAddress
    movlw	G_ADDR_HIGH
    subwf	addr_high, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testBlueAddress
    ; If this is reached, address is the same
    movf        temprc, W
    movwf       temp_duty_g

testBlueAddress
    movlw	B_ADDR_LOW
    subwf	addr_low, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testReset
    movlw	B_ADDR_HIGH
    subwf	addr_high, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testReset
    ; If this is reached, address is the same
    movf        temprc, W
    movwf       temp_duty_b

testReset

    movlw	TOTAL_ADDR_LOW
    subwf	addr_low, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    retfie
    movlw	TOTAL_ADDR_HIGH
    subwf	addr_high, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    retfie

    ; Address counter has reached maximum
    clrf        addr_low
    clrf        addr_high
    retfie

timerprocedure
    bcf         INTCON, TMR0IF
    incfsz	teller
    goto	int_test

    ; End of period:
    ; Setting new duty cycles
    movf    temp_duty_r, W
    movwf   duty_r
    movf    temp_duty_g, W
    movwf   duty_g
    movf    temp_duty_b, W
    movwf   duty_b

    ; Setting LEDs
    movlb	2
    movf    duty_r, W
    bcf     LATA, PIN_R ; Turn off first
    btfss   STATUS, Z
    bsf     LATA, PIN_R	; turn on led

    movf    duty_g, W
    bcf     LATA, PIN_G ; Turn off first
    btfss   STATUS, Z
    bsf     LATA, PIN_G	; turn on led

    movf    duty_b, W
    bcf     LATA, PIN_B ; Turn off first
    btfss   STATUS, Z
    bsf     LATA, PIN_B	; turn on led
    retfie              ; Go back!

int_test
    movlb	2

    ; Test Red duty
    movf	duty_r, W 	; put duty in W
    subwf	teller, W 	; substract values
    btfsc	STATUS, Z 	; if zero detected, execute
    bcf         LATA, PIN_R	; turn off led

    ; Test Green duty
    movf	duty_g, W 	; put duty in W
    subwf	teller, W 	; substract values
    btfsc	STATUS, Z 	; if zero detected, execute
    bcf         LATA, PIN_G	; turn off led

    ; Test Blue duty
    movf	duty_b, W 	; put duty in W
    subwf	teller, W 	; substract values
    btfsc	STATUS, Z 	; if zero detected, execute
    bcf         LATA, PIN_B	; turn off led

    retfie				; and return from interrupt
    ;---------------------------------------

init

    movlw	0x00
    movwf	teller		; Reset teller

    movlw	DUTY_R
    movwf	duty_r		; Load duty cycle
    movwf       temp_duty_r

    movlw	DUTY_G
    movwf	duty_g		; Load duty cycle
    movwf       temp_duty_g

    movlw	DUTY_B
    movwf	duty_b		; Load duty cycle
    movwf       temp_duty_b

    clrf        addr_low
    clrf        addr_high

    ; Set clock speed
    ;movlw	b'10100111' ; Internal clock at 62.5kHz
    movlw	b'01111011' ; Internal clock at 16Mhz
    movlb	1
    movwf	OSCCON

    movlb	3
    clrf	ANSELA 		; All pins digital

    movlb	1
    clrf	ADCON0 		; Disable ADC
    clrf        ADCON1 		; Digital I/O
    clrf	TRISA 		; All pins output
    bsf         TRISA, 5        ; RA5 is input

    movlb	2
;    clrf	LATA 		; turn off all LEDs
    clrf	CM1CON0 	; Disable comparator
    clrf        CM1CON1         ;

;    bsf         LATA, 5

    bsf     APFCON, RXDTSEL ; Set RX to RA5
    bsf     APFCON, TXCKSEL ; Set TX to RA4

    movlb	3

    bsf     BAUDCON, BRG16	; 16 bit baud generator
    bsf     TXSTA, BRGH     ; Set High baud rate

    ; Place 15 in SPBRG
    movlw	0x0F
    movwf	SPBRGL
    clrf	SPBRGH

    movlb   1

    bsf     PIE1, RCIE      ; Enable receive intterrupt
    bcf     PIE1, TXIE      ; Disable transmit interrupts

    movlb   3
    bsf     TXSTA, TXEN     ; Enable transmit
    bsf     RCSTA, RX9      ; 9 bit reading
    bsf     RCSTA, SPEN     ; Enables serial port
    bsf     RCSTA, CREN
    bcf     TXSTA, SYNC     ; Asynch mode

    movlb   1
    bcf     OPTION_REG, TMR0CS 	; Timer op Fosc/4
    bsf     OPTION_REG, PSA 	; DISABLE prescaler
    bcf     OPTION_REG, PS0 	; Set timer prescaler to 1:2
    bcf     OPTION_REG, PS1
    bcf     OPTION_REG, PS2

    bsf     INTCON, PEIE    ; Perpheral interrupts enabled
    bsf     INTCON, TMR0IE  ; Enable timer0 overflow interrupt
    bsf     INTCON, GIE     ; Interrupts on!
main
    nop
    goto	main

debugger
    movlb       3
    movf        addr_high, W
    movwf       TXREG
    movf        addr_low, W
    movwf       TXREG
    return

    end

If you might want to have these boards made by a PCB service (or make it yourself!), here are [url=http://phalox.be/files/DMX_Controller.zip]the files[/url].
What’s in the archive?
* Eagle schematic and board files
* 2 libraries I made
* Gerber files for services like seeedstudio

Note to self: C1 is 1µF and C2 is 100nF

Have fun!

Last week we put the lights to the test for a small party. Because 3 little (9 LED) LED strips is a little lousy for a party, I made some more:

Two full size LED strips were also driven by the tiny DMX receiver boards, so they are capable of something.
Putting all of those strips next to each other is also quite stupid, so I also made 5 extension cables (in total 10m in length):

And this was the result:

Here is an updated version of the firmware.

Changes:
* Added a ‘reset counter by break’ feature, so that less than 512 bytes could be received without breaking anything
* Increased PWM frequency to reduce flickering (with my LED strips, flickering is not visible any more)

Note: I think they are more or less DMX-512 compliant. I’d say they are more forgiving than the strict standard. But, if there are transmission errors in the data packages, a break will be detected and the entire set will be lost or even ‘sent’ to the wrong devices. Just so you know!

#include <p12F1822.inc>
    list p=12f1822, r=dec
;   errorlevel -306 ; no page boundary warnings
;   errorlevel -302 ; no bank 0 warnings
;   errorlevel -202 ; no 'argument out of range' warnings

; Defines addresses
#define R_ADDR_LOW  0x01
#define R_ADDR_HIGH 0x00

; Defines addresses
#define G_ADDR_LOW  0x02
#define G_ADDR_HIGH 0x00

; Defines addresses
#define B_ADDR_LOW  0x03
#define B_ADDR_HIGH 0x00

; Defines starting conditions of pins (useful when no DMX signal is applied)
#define	DUTY_R	0x20
#define	DUTY_G	0xAA
#define	DUTY_B	0xFF

; LED pin locations
#define PIN_R	1
#define PIN_G	2
#define PIN_B	0

; Defines end address (standard is 512)
; The counter is also reset by the break signal, this is an extra check.
; If you want to abuse the DMX-512 protocol (by using more than 512 values),
; Change it here
#define TOTAL_ADDR_LOW  0x00
#define TOTAL_ADDR_HIGH 0x02

; Timer preload that generates timebase for PWM
; This value reduces flickering
#define TIMER_LOAD 0xD0

    __config _CONFIG1, (_FCMEN_OFF & _IESO_OFF & _CLKOUTEN_OFF & _BOREN_ON & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_OFF & _WDTE_OFF & _FOSC_INTOSC) ; 0011 1111 1110 0100
    __config _CONFIG2, (_WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_19 & _LVP_OFF) ; 0001 1110 1111 1111

#define BREAK   0

    cblock 0x70
    cntr        ; 8 bit duty cycle counter
    duty_r
    temp_duty_r
    duty_g
    temp_duty_g
    duty_b
    temp_duty_b
    addr_low    ; Current lower address
    addr_high   ; Current higher address
    temprc      ; Temporary received value
    stat        ; Status register
    endc

    org 0x000
    nop
    goto	init

    org 0x004
    ;---------------------------------------
    ; Interrupt handler
    ;---------------------------------------
    bcf	INTCON, GIE

    movlb   0
    btfsc   PIR1, RCIF
    goto    serialprocedure

    btfsc   INTCON, TMR0IF
    goto    timerprocedure

    

serialprocedure
    movlb	3

    btfss       RCSTA, FERR     ; Test for framing error
    goto        testandinc

    ; A break (or part of the break) has been detected
    movf        RCREG, W        ; Mark register as read
    bsf         stat, BREAK     ; Break has passed, set bit
    movlw       0xFE
    movwf       TXREG
    clrf        addr_low        ; Clear counters
    clrf        addr_high
    retfie


testandinc
    btfss       stat, BREAK     ; Test if break has happened
    goto        serialinc       ; We're past the start sequence

    ; This is the start byte, we don't care about it
    movf        RCREG, W        ; Mark register as read
    bcf         stat, BREAK     ; Clear break bit
    retfie

serialinc
    ; Increment counter
    incf        addr_low, F     ; Increment the Low byte
    btfsc       STATUS, Z       ; Do we have Zero (Multiple of 256)?
    incf        addr_high, F    ; Increment High byte (if necessary)

    movf        RCREG, W        ; Move RCREG in a another variable
    movwf       temprc

    call        debugger

testRedAddress
    movlw	R_ADDR_LOW
    subwf	addr_low, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testGreenAddress
    movlw	R_ADDR_HIGH
    subwf	addr_high, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testGreenAddress
    ; If this is reached, address is the same
    movf        temprc, W
    movwf       temp_duty_r

testGreenAddress
    movlw	G_ADDR_LOW
    subwf	addr_low, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testBlueAddress
    movlw	G_ADDR_HIGH
    subwf	addr_high, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testBlueAddress
    ; If this is reached, address is the same
    movf        temprc, W
    movwf       temp_duty_g

testBlueAddress
    movlw	B_ADDR_LOW
    subwf	addr_low, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testReset
    movlw	B_ADDR_HIGH
    subwf	addr_high, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    goto        testReset
    ; If this is reached, address is the same
    movf        temprc, W
    movwf       temp_duty_b

testReset

    movlw	TOTAL_ADDR_LOW
    subwf	addr_low, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    retfie
    movlw	TOTAL_ADDR_HIGH
    subwf	addr_high, W 	; substract values
    btfss	STATUS, Z 	; if zero detected, skip
    retfie

    ; Address counter has reached maximum
    ; This assures compliance with DMX-512 protocol
    clrf        addr_low        ; Reset counters
    clrf        addr_high
    retfie

timerprocedure
    bcf     INTCON, TMR0IF

    ; Preloading timer value
    movf    TIMER_LOAD, W
    movwf   TMR0

    incfsz  cntr
    goto    int_test

    ; End of period, setting new duty cycles
    movf    temp_duty_r, W
    movwf   duty_r
    movf    temp_duty_g, W
    movwf   duty_g
    movf    temp_duty_b, W
    movwf   duty_b

    ; Setting LEDs
    movlb	2
    movf    duty_r, W
    bcf     LATA, PIN_R ; Turn off first
    btfss   STATUS, Z
    bsf     LATA, PIN_R	; turn on led

    movf    duty_g, W
    bcf     LATA, PIN_G ; Turn off first
    btfss   STATUS, Z
    bsf     LATA, PIN_G	; turn on led

    movf    duty_b, W
    bcf     LATA, PIN_B ; Turn off first
    btfss   STATUS, Z
    bsf     LATA, PIN_B	; turn on led
    retfie

int_test
    movlb	2

    ; Test Red duty
    movf	duty_r, W 	; put duty in W
    subwf	cntr, W 	; substract values
    btfsc	STATUS, Z 	; if zero detected, execute
    bcf         LATA, PIN_R	; turn off led

    ; Test Green duty
    movf	duty_g, W 	; put duty in W
    subwf	cntr, W 	; substract values
    btfsc	STATUS, Z 	; if zero detected, execute
    bcf         LATA, PIN_G	; turn off led

    ; Test Blue duty
    movf	duty_b, W 	; put duty in W
    subwf	cntr, W 	; substract values
    btfsc	STATUS, Z 	; if zero detected, execute
    bcf         LATA, PIN_B	; turn off led

    retfie                      ; and return from interrupt


    ;--------------------------------------------
    ; This is the intialisation and main routine
    ;--------------------------------------------

init

    movlw	0x00
    movwf	cntr		; Reset counter

    movlw	DUTY_R
    movwf	duty_r		; Load duty cycle
    movwf       temp_duty_r

    movlw	DUTY_G
    movwf	duty_g		; Load duty cycle
    movwf       temp_duty_g

    movlw	DUTY_B
    movwf	duty_b		; Load duty cycle
    movwf       temp_duty_b

    clrf        addr_low
    clrf        addr_high

    ; Set clock speed
    movlw	b'01111011'     ; Internal clock at 16Mhz
    movlb	1
    movwf	OSCCON

    movlb	3
    clrf	ANSELA 		; All pins digital

    movlb	1
    clrf	ADCON0 		; Disable ADC
    clrf        ADCON1 		; Digital I/O
    clrf	TRISA 		; All pins output
    bsf         TRISA, 5        ; RA5 is input (UART)

    movlb	2
    clrf	CM1CON0 	; Disable comparator
    clrf        CM1CON1

    bsf     APFCON, RXDTSEL     ; Set RX to RA5
    bsf     APFCON, TXCKSEL     ; Set TX to RA4, only used for debugging purposes

    movlb	3

    ; Configure UART module
    bsf     BAUDCON, BRG16	; 16 bit baud generator
    bsf     TXSTA, BRGH         ; Set High baud rate

    movlw   0x0F                ; Place 15 in SPBRG<0:15>
    movwf   SPBRGL
    clrf    SPBRGH

    movlb   1

    bsf     PIE1, RCIE      ; Enable receive intterrupt
    bcf     PIE1, TXIE      ; Disable transmit interrupts

    movlb   3
    bsf     TXSTA, TXEN     ; Enable transmit
    bsf     RCSTA, RX9      ; 9 bit reading
    bsf     RCSTA, SPEN     ; Enables serial port
    bsf     RCSTA, CREN
    bcf     TXSTA, SYNC     ; Asynch mode

    ; Configure Timer0 module
    movlb   1
    bcf     OPTION_REG, TMR0CS 	; Timer op Fosc/4
    bsf     OPTION_REG, PSA 	; DISABLE prescaler
    bcf     OPTION_REG, PS0 	; Set timer prescaler to 1:2
    bcf     OPTION_REG, PS1
    bcf     OPTION_REG, PS2

    bsf     INTCON, PEIE    ; Perpheral interrupts enabled
    bsf     INTCON, TMR0IE  ; Enable timer0 overflow interrupt
    bsf     INTCON, GIE     ; Interrupts on!

main
    nop
    goto    main

; Writes the current counter values to the transmit UART
debugger
    movlb   3
    movf    addr_high, W
    movwf   TXREG
    movf    addr_low, W
    movwf   TXREG
    return

    end

This is the result:

The flicker you see in the center frame, is because the set value for the LEDs is not full brightness, and therefore it’s using PWM to change the intensity. It’s that flicker frequency that can still be detected by the camera, but no longer by the human eye

Leave a comment

8 Comments

  1. Ben

     /  November 15, 2012

    How do you set dmx start addres.

    Reply
    • admin

       /  November 15, 2012

      I assume that you mean the address for a device (or LED color)?

      Check the source code. At lines 7 through 17, you’ll find the defines for the three colors. You simply ‘glue’ the low and high byte together, and then you know the address. So, they’re actually hard-coded. There are no switches to quickly change them.

      Reply
  2. Nico

     /  December 24, 2012

    Hey, cool project !
    I was asking myself what site/service you used to make your pcb. For small quantity i only know eurocircuit and pcbpool but is it cheaper to do that in hong kong ?

    Reply
    • admin

       /  December 24, 2012

      Welcome here! Nice to see some more Belgian people :-)

      I have been using the PCB service from SeeedStudio in China. There is also iTeadStudio that delivers the same quality. They tend to compete with each other!

      I haven’t come around to moving this article from my old site, so here is a post I made about getting PCB’s made in China: http://phalox.be/flux/viewtopic.php?id=16

      Have fun! If you have any more questions, I’d love to hear them!

      Reply
  3. Nico

     /  December 26, 2012

    Thanks for your quick answer ! I can really see the point of doing those in china. I wonder how they do benefits which such low prices… Anyway, i’ll browse your site when time will be mine. I need to study right now but i’ve many projects in my head waiting to be done ! (including an 8 channels adressable dmx receiver) & Any answers to my questions would be appreciated of course !

    Reply
    • admin

       /  December 26, 2012

      Good luck with exams :-)

      This is my first year after my studies, meaning that I’m working!

      Write your ideas down, it helps clearing your mind of them and you won’t forget them ;-)

      Reply
  4. kishan

     /  December 30, 2012

    what about the USB Connectivity module details it isn’t given anywhere :( i need it to make the USB Connectivity and also is it possible to connect multiple DMX Receiver with the help of IN n OUT DMX Pins

    Reply
  5. admin

     /  December 30, 2012

    You’ve got a point, I never really discussed that.
    In fact it’s quite simple: I am using a USB to UART converter board (the black one). Mine contains a FT232RL chip. You can find these kinds of boards on multiple places (check ebay!).

    Next, we need to make a RS485 signal. The only difference with UART, is that this is a differential signal (one line is high, the other is low and vice versa) and it works on different voltages.
    I am using a MAX485 (but there are cheaper version not from Maxim). This is actually a transceiver (can transmit and receive, but not at the same time), but I am using it as a transmitter only (DMX is one way traffic!). Have a look at the datasheet of this chip: http://www.usconverters.com/downloads/max491.pdf

    For transmission function, you have to connect:
    * /RE to 5V -> this DISABLES receive
    * DE to 5V -> this ENABLES transmit
    * RO can be left open. I think you can also connect to GND
    * DI is the input of the chip
    * Power stuff, can simply be powered by the 5V and GND coming from the FT232RL board.

    Connect the TX line of the FT232RL to DI of MAX485, the A and B output of the MAX 485 are your DMX signal. Make sure you don’t swap them, because then all your information is inverted!

    PS: you can also find USB->DMX modules on Ebay, but I don’t know how they work…

    Your last question: Yes! DMX is a bus, so you can attach as many modules as you want (as long as your bus can handle it, and you don’t cross the 512 limit). Normally they connect a lot less nodes per bus.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>