Author Topic: Building a PIC based DMX Dimmer - Problems  (Read 8552 times)

0 Members and 1 Guest are viewing this topic.

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 598
  • Country: za
    • ShoutingElectronics.com
Building a PIC based DMX Dimmer - Problems
« on: August 09, 2014, 09:24:22 pm »
Good day all.
I am trying to build a DMX-512 receiver.

I am testing it using a DMXCreator USB Dongle that is working, as it runs other lighting.
I have the dongle connected directly to my Max485 chip, without any thing else on the bus.

I am using a PIC18F2420 uC, with a MAX485 Transceiver connected to the USART RX pin (RC7).
I have read AP1076, but prefer to code in C18.

I have taken the code from :
http://dbprototyping.com/dmxTXRX.htm
This code is for the 18f46k20, which they operate at 16Mhz. My pic is set to operate at 8Mhz which is it's maximum,

I have taken their code, and changed some of the config settings that were not compatible with my Pic. I have also recalculated the SPBRG to be 7 (instead of the 15 they used).

But the problem is that I am not seeing the Framing error.
If you see, I have put XLCD writes to help with my debugging, and it gets to the point where it writes a 3, then because FRAME_ERROR==0, it loops back using the goto WaitBreak step.

Please, any suggestions why it would not see the Framing Error (Even if I take that PIC pin high or low with a jumper, it does not even generate the error. Suggestions would be welcome. My code is below. Thanks :

Code: [Select]
/*
 * File:   DMXRecv.c
 * Author: Peter
 *
 * Created on 09 August 2014, 17:26
 */

/** C O N F I G U R A T I O N   B I T S ******************************/

#pragma config OSC = INTIO67, FCMEN = OFF, IESO = OFF                     // CONFIG1H
#pragma config PWRT = OFF, BOREN = OFF //,BORV = 30                       // CONFIG2L
#pragma config WDT = OFF, WDTPS = 32768                                   // CONFIG2H
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTB    // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF                        // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF //, CP2 = OFF, CP3 = OFF              // CONFIG5L
#pragma config CPB = OFF, CPD = OFF                                       // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF//, WRT2 = OFF, WRT3 = OFF           // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                         // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF//, EBTR2 = OFF, EBTR3 = OFF       // CONFIG7L
#pragma config EBTRB = OFF                                                // CONFIG7H

/** I N C L U D E S **************************************************/

#include <timers.h>
#include <string.h>
#include <usart.h>
#include <pwm.h>
#include <stdio.h>
#include <stdlib.h>
#include <delays.h>
#include "xlcd.h"
/*
 *
 */

 /** PROTOTYPES *****************************************************/
 void setup_usart(void);  // setup baud rate etc. of USART
 void setup_pwm(void); // setup pwm etc

/* declare statically allocated uinitialized variables *********/
#pragma udata

char RXbuffer[128];
char DataVal = 0;
int slot = 0;
int channel = 1;

/* Declare executable instructions ****************************/
//#pragma code

// Delays for XLCD.h
void DelayFor18TCY( void ) { Delay10TCYx(2); }
void DelayPORXLCD( void ) { Delay1KTCYx(10); }
void DelayXLCD( void ) { Delay10TCYx(5); }

void main(void) {
    // set internal oscillator to 16MHz
    OSCCON = 0x70;          // IRCFx = 111
    OSCTUNEbits.PLLEN = 0;  // x4 PLL disabled

    LATA=0x00;
    LATB=0x00;
    LATC=0x00;
    TRISA=0x00;
    TRISB=0x00;
    TRISC=0xFF;

    //INITIALISE THE LCD
    while( BusyXLCD() );
    OpenXLCD(  FOUR_BIT & LINES_5X7);
    WriteCmdXLCD( BLINK_OFF & CURSOR_OFF);
    WriteCmdXLCD( SHIFT_DISP_LEFT );
    while ( BusyXLCD());
    //BANNER
    putrsXLCD("DMX Buddy v1.0");

// ########## NOW THE DMX ROUTINES
    memset(RXbuffer, 0, 128); // clear RXbuffer

setup_usart(); // setup USART
// setup_pwm(); // setup PWM & timer2

while(1)
{
/* Synchronise with the transmitter - wait fro break */

WaitBreak:
        WriteCmdXLCD ((0x80+0x39)); //Line 2
        putrsXLCD("1 ");
if (DataRdyUSART()) { ReadUSART(); } // if byte received correctly discard it
        putrsXLCD("2 ");
        if (USART_Status.FRAME_ERROR == 0) // wait for framing error
{ putrsXLCD("3 ");
            goto WaitBreak; } // loop till framing error detected
        putrsXLCD("4 ");
ReadUSART(); // read USART to clear error
       
/* Wait for the START code */

        putrsXLCD("5 ");
WaitStart:
while(!DataRdyUSART());// wait until byte received

        putrsXLCD("6 ");

if(USART_Status.FRAME_ERROR == 1) // if framing error wait start
{
goto WaitStart;
}
        WriteCmdXLCD ((0x80+0x49));
        putrsXLCD("RD ");

if (ReadUSART() != 0) goto WaitBreak; // read the data & check if 0
/* Receive 512 bytes of data */

for (slot=0; slot<128; slot++)
{
if (RCSTAbits.FERR == 1) break; // check for framing error

                while (!DataRdyUSART()); // wait for data to be available
               // LATCbits.LATC4=0;
                RXbuffer[slot] = ReadUSART(); // read and copy data to RXbuffer
                //LATCbits.LATC4=1;
        }

/* When frame complete use selected channel to control PWM duty cycle */
//CCPR1L = RXbuffer[1]; // get value and set PWM duty cycle

     
// Output the string a character at a time
        //WriteCmdXLCD ((0x80+0x4C));
        //putrsXLCD("Egg");
       // if (CCPR1L>=128) { putrsXLCD(">128"); };
       // if (CCPR1L<=128) { putrsXLCD("<128"); };
        //putrsXLCD("Egg");

        //}


        //        itoa((RXbuffer[4]),cvalue);
                 //End of Line 2
             
                //  putrsXLCD(cvalue);
        }


}

void setup_usart(void) // Set USART to transmit @ 250KB
{
OpenUSART(      USART_TX_INT_OFF & // disable TX interrupt
USART_RX_INT_OFF & // enable RX interrupt
USART_ASYNCH_MODE & // set asynchronous mode
USART_EIGHT_BIT & // set 9-bit data mode
USART_CONT_RX & // set port continues RX
USART_BRGH_HIGH, 7); // uses high speed formula, 250KBd
                        BAUDCONbits.BRG16 = 1; // set 16 bit async mode
}

void setup_pwm(void) // setup PWM etc
{

OpenTimer2( TIMER_INT_OFF & T2_PS_1_1); // enable timer 2, prescaler = 1:1
OpenPWM2(255); // PR2 = 249 Timer 2 Period Register
// SetOutputPWM2( FULL_OUT_FWD, PWM_MODE_1 ); // CCP1CON = 0b01001100
        SetDCPWM2(2);
}
« Last Edit: August 12, 2014, 08:21:21 pm by kolbep »
====================================
www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel
 

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 598
  • Country: za
    • ShoutingElectronics.com
Re: PIC Not seeing Framing Error - DMX Receiver
« Reply #1 on: August 10, 2014, 09:29:03 am »
Bump...
====================================
www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13772
  • Country: gb
    • Mike's Electric Stuff
Re: PIC Not seeing Framing Error - DMX Receiver
« Reply #2 on: August 10, 2014, 10:07:06 am »
Have you verified that the UART is running at the right rate, by sending bytes and checking on a scope?
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 598
  • Country: za
    • ShoutingElectronics.com
Re: PIC Not seeing Framing Error - DMX Receiver
« Reply #3 on: August 10, 2014, 06:12:43 pm »
I tried something to that effect,
where I scoped the DMX signal that was going INTO my uC from the Max485, and tried to see what the duration of the bit is (just to get an idea of how long it is), but it looks like about 35uS (Scope set on 10uS/div. I think it is supposed to be something like 4uS per bit, but the edges are not clear. It looks like overlapping from several bits being shown during at the same time (from say a couple of sweeps)

I only have an analogue 20mhz scope, so I don't know how to get clear accurate reading.

I Sent a char 'U' out on the Usart, but the bit time does look to be 4uS.

I even took the ASM version directly from the Appnote, and made some changes to the config bits, as well as setting the registers to up the speed to the 8mhz of my Micro, and then adjusted the SPBRG from 15 down to 7 (some calculators say it must be 1),
but that is also just hanging around the same point...
 :wtf:

And I thought this was going to be an easy one.  |O

Maybe there is something different about the 18f2420 micro that messes it up.
====================================
www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel
 

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 598
  • Country: za
    • ShoutingElectronics.com
Re: Building a PIC based DMX Dimmer - Problems
« Reply #4 on: August 12, 2014, 08:27:58 pm »
Having dug around a lot on the net, I see that lots of people discourage using frame error to detect the long break.
So I am trying my own code, where a High to Low transition on RB2 triggers an interrupt.
In the interrupt it resets timer1, and then sets a edge flag, it also changes the interrupt edge detection for the next part to trigger an interrupt on low to high.

Then when the interrupt occurs, it reads off the timer1. If it is a low time, then ignore it because it is probably a bit. If it is longer than 128 Cycles in the timer, then it is most likely the 176ms break. In which case it sets a flag for the long break detection, and drops out of the ISR.

My main loop then keeps on polling this flag. As soon as the flag goes high, it is supposed to start reading from the USART.

I have a problem when, If I enable Timer1's T1_SOURCE_INT, it stops my program from ever going into the ISR (Even though I do not even have Interrupts enabled for Timer1)

Any clues.....

Thanks for all your help

Code: [Select]
/*
 * File:   DMXRecv.c
 * Author: Peter
 *
 * Created on 09 August 2014, 17:26
 */

/** C O N F I G U R A T I O N   B I T S ******************************/

#pragma config OSC = INTIO67, FCMEN = OFF, IESO = OFF                     // CONFIG1H
#pragma config PWRT = OFF, BOREN = OFF //,BORV = 30                       // CONFIG2L
#pragma config WDT = OFF, WDTPS = 32768                                   // CONFIG2H
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTB    // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF                        // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF //, CP2 = OFF, CP3 = OFF              // CONFIG5L
#pragma config CPB = OFF, CPD = OFF                                       // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF//, WRT2 = OFF, WRT3 = OFF           // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                         // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF//, EBTR2 = OFF, EBTR3 = OFF       // CONFIG7L
#pragma config EBTRB = OFF                                                // CONFIG7H

/** I N C L U D E S **************************************************/

#include <timers.h>
#include <string.h>
#include <usart.h>
#include <pwm.h>
#include <stdio.h>
#include <stdlib.h>
#include <delays.h>
#include "xlcd.h"
#include <portb.h>
/*
 *
 */

 /** PROTOTYPES *****************************************************/
 void setup_usart(void);  // setup baud rate etc. of USART
 void setup_pwm(void); // setup pwm etc

/* declare statically allocated uinitialized variables *********/
#pragma udata

char RXbuffer[64];
char DataVal = 0;
int slot = 0;
int channel = 1;
int brkfl;
unsigned int t1val;
char at1val;
int lbflag;     //THIS FLAG SAYS THERE IS A LONG BREAK, SO START USART
char chanval;

/* Declare executable instructions ****************************/
//#pragma code

// Delays for XLCD.h
void DelayFor18TCY( void ) { Delay1KTCYx(12); }
void DelayPORXLCD( void ) { Delay10KTCYx(100); }
void DelayXLCD( void ) { Delay1KTCYx(11); }


void reset (void) { //This Routine will reset the uC
    _asm reset _endasm
}

void high_interrupt (void); /* prototype needed for 'goto' below */
#pragma code HIGH_INTERRUPT_VECTOR = 0x8
void high_ISR (void)
{
_asm
goto high_interrupt
_endasm
}
#pragma code /* allow the linker to locate the remaining code */

#pragma interrupt high_interrupt
void high_interrupt (void) {
    putrsXLCD ("Abcd ");
    if (INTCON3bits.INT2IF==1) {
putrsXLCD("B ");
        if (brkfl==0) {     //THIS WAS A HIGH TO LOW
            WriteTimer1(0); //RESET THE TIMER
putrsXLCD("C ");
            INTCON2bits.INTEDG2=1;  //Change to rising edge
            PORTB=PORTB;            //Clear Mismatch
            brkfl=1;        //Change the Flag so we know next step
        };
        if (brkfl==1) {     //THIS WAS A LOW TO HIGH
putrsXLCD("P ");
            t1val=ReadTimer1();
            INTCON2bits.INTEDG2=0;  //Change to falling edge detection
            PORTB=PORTB;            //Clear Mismatch
            brkfl=0;
            while(BusyXLCD());      //Wait for LCD
            itoa(t1val,at1val);     // Convert to Ascii

           putsXLCD(at1val);
           putrsXLCD(" ");
            if (t1val>=128) {
                //THIS IS A LONG BREAK, SO WE CAN START THE USART
                lbflag=1;
               //putsXLCD(at1val);
                putrsXLCD("D ");
                while(1);
            };
        };
        };

      INTCON3bits.INT2IF=0;  //ByeByeFlag

    INTCON3bits.INT1IF =0;  //Re-en``able all interrupts
}

void EnableHighInterrupts (void)
{
RCONbits.IPEN = 1; /* enable interrupt priority levels */
INTCONbits.GIEH = 1; /* enable all high priority interrupts */
}

#pragma interrupt low_interrupt
void low_interrupt (void) {
    WriteCmdXLCD ((0x80+0x42));
    putrsXLCD("HEY A LOW");
//    INTCON3bits.INT1IF =0;  //Re-enable all interrupts
    while(1);
}

void EnableLowInterrupts (void)
{
RCONbits.IPEN = 1; /* enable interrupt priority levels */
INTCONbits.GIEL = 1; /* enable all high priority interrupts */
}


void main(void) {
    // set internal oscillator to 16MHz
    OSCCON = 0x60;          // IRCFx = 110    MAKES CLOCK 4MHZ
    OSCTUNEbits.PLLEN = 1;  // x4 PLL         MAKES CLOCK 16MHZ
   
    LATA=0x00;
    LATB=0x00;
    LATC=0x00;
    TRISA=0x00;         // 0=OUT, 1=IN
    TRISB=0x00;//&0x04;         // O=OUT, 1=IN
    TRISB=0xFF;
    TRISC=0xFF;         // O=OUT, 1=IN
    //INITIALISE THE LCD
 //   while( BusyXLCD() );
    OpenXLCD(  FOUR_BIT & LINES_5X7);
    WriteCmdXLCD( BLINK_OFF & CURSOR_OFF);
    WriteCmdXLCD( SHIFT_DISP_LEFT );
 //   while ( BusyXLCD());
    //BANNER
    putrsXLCD("DMX Buddy v1.1  ");

     OpenTimer1( TIMER_INT_OFF &
                T1_8BIT_RW &
                T1_SOURCE_INT &
                T1_PS_1_8 &
                T1_OSC1EN_OFF &
                T1_SYNC_EXT_OFF );
    PIE1bits.TMR1IE=0;
     IPR1bits.TMR1IP=0;
  //  setup_usart();

    //SETUP PORT RB2 FOR HIGH TO LOW FOR BREAK DETECTION
    //CAUSES INTERRUPT
    brkfl=0;
    OpenRB2INT( PORTB_CHANGE_INT_ON & FALLING_EDGE_INT & PORTB_PULLUPS_ON);

//    RCONbits.IPEN = 0;          // priority
    INTCONbits.GIE = 1;         // enable interrupt
    INTCONbits.RBIE = 1;        // interrupt portB on

    EnableHighInterrupts;
    EnableLowInterrupts;

   

    while(1) {  //MAIN LOOP
        if (lbflag==1) {        //Long Break Detected. Start the USART Receing
            lbflag=0;
           putrsXLCD("pwpwpwpwpwpwpw");
            ReadUSART();    //Clear any errors

           /* Receive 512 bytes of data */

        for (slot=0; slot<64; slot++)
{
// if (RCSTAbits.FERR == 1) break; // check for framing error
while (!DataRdyUSART()); // wait for data to be available
RXbuffer[slot] = ReadUSART(); // read and copy data to RXbuffer
}

            itoa((RXbuffer[5]),chanval);
            putsXLCD(at1val);
            putrsXLCD("- -");
        };
    };
}

void setup_usart(void) // Set USART to transmit @ 250KB
{
OpenUSART(      USART_TX_INT_OFF & // disable TX interrupt
USART_RX_INT_OFF & // enable RX interrupt
USART_ASYNCH_MODE & // set asynchronous mode
USART_NINE_BIT & // set 9-bit data mode
USART_CONT_RX & // set port continues RX
USART_BRGH_HIGH, 15); // uses high speed formula, 250KBd
                        BAUDCONbits.BRG16 = 1; // set 16 bit async mode
}

====================================
www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Building a PIC based DMX Dimmer - Problems
« Reply #5 on: August 12, 2014, 08:43:25 pm »
Code: [Select]
            while(BusyXLCD());      //Wait for LCD
            itoa(t1val,at1val);     // Convert to Ascii
[/quote]

1) try not loop around in an isr; you want it to be quick;
2) Those xlcd routines are probably long. Also, you will need to make sure that they are not used outside of the isr as well;
3) itoa() routines are often very long.

[quote]So I am trying my own code, where a High to Low transition on RB2 triggers an interrupt.
In the interrupt it resets timer1, and then sets a edge flag, it also changes the interrupt edge detection for the next part to trigger an interrupt on low to high.

Then when the interrupt occurs, it reads off the timer1. If it is a low time, then ignore it because it is probably a bit. If it is longer than 128 Cycles in the timer, then it is most likely the 176ms break. In which case it sets a flag for the long break detection, and drops out of the ISR.
[/quote]

That is fairly simple and can be done fairly easily. Two suggestions:

1) Need to make sure that the timer can detect overflow.
2) Use a constantly running timer;

If you are running out of external interrupts, use pin-change interrupts here -> will make your coding simpler.

Also, consider the use of capture.
================================
https://dannyelectronics.wordpress.com/
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13772
  • Country: gb
    • Mike's Electric Stuff
Re: Building a PIC based DMX Dimmer - Problems
« Reply #6 on: August 12, 2014, 10:28:46 pm »
Having dug around a lot on the net, I see that lots of people discourage using frame error to detect the long break.
The only reason to not do that is if there are issues with a particular device - check the errata
A break should generally show up as a zero byte as well as setting the FERR flag.
[/quote]
So I am trying my own code, where a High to Low transition on RB2 triggers an interrupt.
In the interrupt it resets timer1, and then sets a edge flag, it also changes the interrupt edge detection for the next part to trigger an interrupt on low to high.
[/quote]
It's easier than that. Int on -ve edge sets a timer int. to fire in the normal stopbit position.
The timer int samples the input and if low, you have a break.

Quote

My main loop then keeps on polling this flag. As soon as the flag goes high, it is supposed to start reading from the USART.


Why would you do this in foreground? Much easier if all the DMX acquistion, including addressing, is done under interrupts, and just throws a flag to the foreground task when a frame is received.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 598
  • Country: za
    • ShoutingElectronics.com
Re: Building a PIC based DMX Dimmer - Problems
« Reply #7 on: August 13, 2014, 06:07:47 am »
The only reason to not do that is if there are issues with a particular device - check the errata

Pickit2 is reporting my Silicon as rev 07. Here are all the errata for all the revisions, does anything stand out as being the cause of the Framing Error not being detected :
Code: [Select]
18. Module: EUSART
When performing back-to-back transmission in
9-bit mode (TX9D bit in the TXSTA register is
set), an ongoing transmissionís timing can be
corrupted if the TX9D bit (for the next
transmission) is not written immediately following the setting of TXIF. This is because any
write to the TXSTA register results in a reset of
the baud rate timer which will effect any ongoing
transmission.
Work around
Load TX9D just after TXIF is set, either by polling
TXIF or by writing TX9D at the beginning of the
Interrupt Service Routine, or only write to TX9D
when a transmission is not in progress
(TRMT = 1).

19. Module: EUSART
When performing back-to-back transmission in 9-bit
mode (TX9D bit in the TXSTA register is set), the
second byte may be corrupted if it is written into
TXREG immediately after the TMRT bit is set.
Work around
Execute a software delay, at least one-half the
transmissionís bit time, after TMRT is set and prior
to writing subsequent bytes into TXREG.
Date Codes that pertain to this issue:
All engineering and production devices.

6. Module: Enhanced Universal
Synchronous Receiver
Transmitter (EUSART)
One bit has been added to the BAUDCON register
and one bit has been renamed. The added bit is
RXDTP and is in the location, BAUDCON<5>. The
renamed bit is the TXCKP bit (BAUDCON<4>),
which had been named SCKP.
The TXCKP (BAUDCON<4>) and RXDTP
(BAUDCON<5>) bits enable the Synchronous
mode TX and RX signals to be inverted (polarity
reversed). RXDTP has no effect on the
Synchronous mode DT signal.
Register 18-3, on page 204, will be changed as
shown.
Work around
None required.
Date Codes that pertain to this issue:
All engineering and production devices.

5. Module: Enhanced Universal
Synchronous Asynchronous
Receiver Transmitter (EUSART)
In rare situations when interrupts are enabled,
unexpected results may occur if:
• The EUSART is disabled (the SPEN bit,
RCSTA <7>, = 0)
• The EUSART is re-enabled (RCSTA <7> = 1)
• A two-cycle instruction is executed
Work around
Add a 2-TCY delay after re-enabling the EUSART.
1. Disable Receive Interrupts (RCIE bit,
PIE1<5>, = 0).
2. Disable the EUSART (RCSTA <7>, = 0).
3. Re-enable the EUSART (RCSTA <7> = 1).
4. Re-enable Receive Interrupts (PIE1<5> = 1).
(This is the first TCY delay.)
5. Execute an NOP instruction.
(This is the second TCY delay.)

Quote
It's easier than that. Int on -ve edge sets a timer int. to fire in the normal stopbit position.
The timer int samples the input and if low, you have a break.

Before this project, the furtherest I managed to get with the PIC was flashing LEDS, A countdown timer, and Reading Voltages using the ADC. I would really appreciate if you could please show me a snippet of code that describes what you say above. I am having a bit of hassle comprehending it. Does it mean that I must set up the timer with a period corresponding to 4m/s, then when the pin goes -ve edge, reset the Timer and enable interupt. Then in that interrupt I must look if the pin is still low?

I know the itoa and xlcd are processor hogs, I just wanted an easy way for me to read out timings, etc, while I am trying to debug. Once I am far enough along, I can remove them...

Thanks for the help
====================================
www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Building a PIC based DMX Dimmer - Problems
« Reply #8 on: August 13, 2014, 10:34:30 am »
It is much better for you if you write the code - we can help you get there.

The isr would basically look like this:

Code: [Select]
  //this is pcint
  if (sensor pin is high) { //the pin must have gone through a low->high transition -> rising edge
    reset timer;
    clear sTimer's value;
  } else {                       //the pin is low -> it must have gone through a high->low transistion -> falling edge
    save timer's value to sTimer; //save timer's value into a shadow variable
    set a flag to indicate new data;
  }

...in main...
  if (flag is set) { //new data has arrived
    if (sTimer > TIMER_THRESHOLD) { //this is a long pulse
      //do something
    } else { //pulse is short
      //do something else
    }

Hope it helps.
================================
https://dannyelectronics.wordpress.com/
 

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 598
  • Country: za
    • ShoutingElectronics.com
Re: Building a PIC based DMX Dimmer - Problems
« Reply #9 on: August 13, 2014, 05:11:17 pm »
Ok, I am trying the basics now, just to understand the USART. Reading the usart and check for Framing errors.
If I have the RC7 pin connected to the Max485, I expect it to display random values, and to indicate a framing error. But all I get printed on the XLCD is -4   and the bit indicating framing error never comes up...

Here is my code:
Code: [Select]
/*
 * File:   DMXRecv.c
 * Author: Peter
 *
 * Created on 09 August 2014, 17:26
 */

/** C O N F I G U R A T I O N   B I T S ******************************/

#pragma config OSC = INTIO67, FCMEN = OFF, IESO = OFF                     // CONFIG1H
#pragma config PWRT = OFF, BOREN = OFF //,BORV = 30                       // CONFIG2L
#pragma config WDT = OFF, WDTPS = 32768                                   // CONFIG2H
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTB    // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF                        // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF //, CP2 = OFF, CP3 = OFF              // CONFIG5L
#pragma config CPB = OFF, CPD = OFF                                       // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF//, WRT2 = OFF, WRT3 = OFF           // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                         // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF//, EBTR2 = OFF, EBTR3 = OFF       // CONFIG7L
#pragma config EBTRB = OFF                                                // CONFIG7H

/** I N C L U D E S **************************************************/

#include <timers.h>
#include <string.h>
#include <usart.h>
#include <pwm.h>
#include <stdio.h>
#include <stdlib.h>
#include <delays.h>
#include "xlcd.h"

unsigned int usartval;
unsigned char ausartval;
//#include <porta>
/*
 *
 */

 /** PROTOTYPES *****************************************************/
 void setup_usart(void);  // setup baud rate etc. of USART


/* Declare executable instructions ****************************/
// Delays for XLCD.h
void DelayFor18TCY( void ) { Delay1KTCYx(1); }
void DelayPORXLCD( void ) { Delay1KTCYx(10); }
void DelayXLCD( void ) { Delay1KTCYx(1); }


void reset (void) { //This Routine will reset the uC
    _asm reset _endasm
}

void high_interrupt (void); /* prototype needed for 'goto' below */
#pragma code HIGH_INTERRUPT_VECTOR = 0x8
void high_ISR (void)
{
_asm
goto high_interrupt
_endasm
}
#pragma code /* allow the linker to locate the remaining code */

#pragma interrupt high_interrupt
void high_interrupt (void) {
}

void EnableHighInterrupts (void)
{
    RCONbits.IPEN = 1; /* enable interrupt priority levels */
    INTCONbits.GIEH = 1; /* enable all high priority interrupts */
}

void main(void) {
    // set internal oscillator to 16MHz
    OSCCON = 0x60;          // IRCFx = 110    MAKES CLOCK 4MHZ
    OSCTUNEbits.PLLEN = 1;  // x4 PLL         MAKES CLOCK 16MHZ
   
    LATA=0x00;
    LATB=0x00;
    LATC=0x00;
    TRISA=0x00;         // 0=OUT, 1=IN
    TRISB=0x00;         // O=OUT, 1=IN
    TRISC=0xff;         // O=OUT, 1=IN
    //INITIALISE THE LCD

    //while( BusyXLCD() );
    OpenXLCD(  FOUR_BIT & LINES_5X7);
    WriteCmdXLCD( BLINK_OFF & CURSOR_OFF);
    WriteCmdXLCD( SHIFT_DISP_LEFT );
 
    putrsXLCD("DMX Buddy v2.1  ");
///////////////////////////////////////////////////////////////////////////////
//    LETS TEST THE USART FOR FRAMING ERRORS
    setup_usart();
    PORTAbits.RA7=0;    //CLEAR THE LED

    while(1){
        int usartval=ReadUSART();
        itoa (usartval,ausartval);
        putsXLCD(ausartval);
        putrsXLCD("  ");
        Delay10KTCYx(500);
         if (RCSTAbits.FERR){
         PORTAbits.RA7=1;
        }

    };
 

    EnableHighInterrupts;
 
   

    while(1) {  //MAIN LOOP

    };
}

    void setup_usart(void) // Set USART to transmit @ 250KB
    {
OpenUSART(      USART_TX_INT_OFF & // disable TX interrupt
USART_RX_INT_OFF & // enable RX interrupt
USART_ASYNCH_MODE & // set asynchronous mode
USART_NINE_BIT & // set 9-bit data mode
USART_CONT_RX & // set port continues RX
USART_BRGH_HIGH, 15); // uses high speed formula, 250KBd
                        BAUDCONbits.BRG16 = 1; // set 16 bit async mode
    }


Where can I start looking for this (my) bug???
====================================
www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel
 

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 598
  • Country: za
    • ShoutingElectronics.com
Re: Building a PIC based DMX Dimmer - Problems
« Reply #10 on: August 13, 2014, 08:38:16 pm »
Looks like I am getting Frame Errors, after setting every bit manunally, and not using the OpenUSART routine (At least my Test Light on RA7 is coming on):
Now to figure out why it is still showing 0 on the LCD, instead of another random value.....

Code: [Select]
///////////////////////////////////////////////////////////////////////////////
//    LETS TEST THE USART FOR FRAMING ERRORS
//    setup_usart();
//    Delay10KTCYx(100);
// putrsXLCD("DMX Buddy v2.3  ");

    while(1) {
    PORTAbits.RA7=0;

    SPBRGH=.15;
    TRISCbits.TRISC7=1;
    TRISCbits.TRISC6=1;
    TXSTAbits.TXEN=0;   //DISABLE TX
    TXSTAbits.BRGH=1;
    BAUDCONbits.BRG16=1;
    TXSTAbits.SYNC=0;
    RCSTAbits.SPEN=1;   //ENABLE SerialP
    RCSTAbits.RX9=1;
    RCSTAbits.ADDEN=0;  //??????
    RCSTAbits.CREN=1;   //ENABLE RX


 //   while(!(PIR1bits.RCIF));    //WAIT FOR RECEPTION COMPLETE

   // if(RCSTAbits.FERR){
   //     PORTAbits.RA7=1;
   //     recvreg=RCREG;                          //CLEAR THE ERROR
   // };

    while(RCSTAbits.FERR) {
     recvreg=RCREG;
     PORTAbits.RA7=1;
      };

    //while(!(PIR1bits.RCIF));    //WAIT FOR ANOTHER BYTE
    //PIR1bits.RCIF=0;
    //while(!(RCSTAbits.FERR)) {
        PORTAbits.RA7=0;
        recvreg=RCREG;
        itoa(recvreg,arecvreg);
        //Delay10KTCYx(1);
        //putsXLCD(arecvreg);
        Delay10KTCYx(1);
        putsXLCD(arecvreg);
        putrsXLCD(". ");
    }
====================================
www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13772
  • Country: gb
    • Mike's Electric Stuff
Re: Building a PIC based DMX Dimmer - Problems
« Reply #11 on: August 13, 2014, 10:18:59 pm »
Beware peripheral libraries - they may be hiding stuff from you. Best to bash the hardware direct if doing something vaguely nonstandard
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline matkar

  • Regular Contributor
  • *
  • Posts: 153
  • Country: si
  • Sixty percent of the time it works EVERY time.
Re: Building a PIC based DMX Dimmer - Problems
« Reply #12 on: August 14, 2014, 09:12:11 pm »
I have taken their code, and changed some of the config settings that were not compatible with my Pic. I have also recalculated the SPBRG to be 7 (instead of the 15 they used).

SPBRG values of less than 10 can lead to inaccurate bitrate settings. Here below is a macro that calculates adequate baudrate according to your clock. It's written in assembler, but you'll get the idea.

Code: [Select]
SERIAL_1_INIT_PORT

#define     BRGH_HIGH       ;Select for BRGH=1

SPBRG_V1 = CLOCK_FREQ/UARTINT_BAUDRATE;

SPBRG_V2 = SPBRG_V1 /.16   ;
SPBRG_V22 = (SPBRG_V1 * .10) /.16   ;
        if ( ((SPBRG_V2*.10) - SPBRG_V22) >= .5)
        SPBRG_V2 ++;
        endif


        if (SPBRG_V2 > 0xff)
        SPBRG_V3 = SPBRG_V2

        SPBRG_V2 = SPBRG_V3 / .4
        SPBRG_V22 = (SPBRG_V3 * .10) /.4   ;
        if ( ((SPBRG_V2*.10) - SPBRG_V22) >= .5)
                SPBRG_V2 ++;
        endif
       
        #undefine   BRGH_HIGH   ;BRGH = 0
        endif

        bsf     TXSTA,BRGH              ;Enable BRGH
SPBRG_VAL=SPBRG_V2 - D'1'   ;Calculated SPBRG register value

    if SPBRG_VAL > .255
        error "Calculated SPBRG register value is out of range"
    endif

    if SPBRG_VAL <= .10
        error "Calculated SPBRG register value is too low"
    endif


#ifndef SPBRG_VAL
error "SPBRG reload value not def."
#endif

movlw SPBRG_VAL
movwf   SPBRG
bcf TXSTA,SYNC      ; Async
bsf RCSTA,SPEN      ; serial 1 enable

bcf TXSTA,TX9       ; Tx 8-bit
bsf TXSTA,TXEN      ; Tx enabled
bcf RCSTA,RX9       ; Rx 8-bit
bsf RCSTA,CREN      ; Rx enabled

; bcf IPR1,RCIP ; set serial 1 Rx interrupt as low priority
bsf PIE1,RCIE       ; enable Rx interrupt
        bcf RCON,IPEN       ; single interrupt priority mode selection
bsf INTCON,GIE      ; enable global priority interrupt
bsf INTCON,PEIE     ; enable peripheral interrupt

return
 

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 598
  • Country: za
    • ShoutingElectronics.com
Re: Building a PIC based DMX Dimmer - Problems
« Reply #13 on: August 22, 2014, 05:05:16 pm »
Now that there is a time crunch, and the fact that I can only borrow a USB Dmx dongle for a few days at a time every couple of weeks,
I have decided to go with a tried and tested method.

http://dbprototyping.com/dmxTXRX.htm
has taken the Microchip Appnote, and converted it to work with C18 and the PIC18F4xK20 series.

I have ordered myself the same chip that they use, then I will modify their code to my own needs (They just have PWM dimming, but I want to make it modular so that I can have Relay Output, Phase Controlled Triac, and PWM'd transistor outputs (or a combination).

I know it is a bit of a cheat, and I am upset that I have to resort to this. It would be more satisfying to have figured out why it does not work with the PIC18F2420 series, but time is against me....
====================================
www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf