• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Traffic Lights Program using flowcode

Status
Not open for further replies.

skeeterb

Member
I've been working on this for a while with the help of 3v0 in the chat room, and have gotten this code working. Using a potentiometer or preset you can adjust the timing of this code from 1 second to 60 seconds. The Red/Green timing is calculated using the formula 1+((rslt+1)/17) to determine the timing for the Red to Green change and the Green to Amber is half of the value of the Red to Green variable.

here is the code and the images generated by FlowCode.

Code:
//************************************************************************************
//**  
//**  File name:     C:\temp\Traffic Light.c
//**  Generated by:  Flowcode v4.0.0.53
//**  Date:          Monday, June 29, 2009 17:18:35
//**  Licence:       Demo
//**  
//**        ***DEMO VERSION***
//**  
//**  
//**     NOT FOR COMMERCIAL USE
//**  
//**  http://www.matrixmultimedia.com
//************************************************************************************


#define MX_PIC

//Defines for microcontroller
#define P16F690
#define MX_EE
#define MX_EE_SIZE 256
#define MX_SPI
#define MX_SPI_BCB
#define MX_SPI_SDI 4
#define MX_SPI_SDO 7
#define MX_SPI_SCK 6
#define MX_UART
#define MX_UART_B
#define MX_UART_TX 7
#define MX_UART_RX 5
#define MX_I2C
#define MX_MI2C
#define MX_I2C_B
#define MX_I2C_SDA 4
#define MX_I2C_SCL 6
#define MX_PWM
#define MX_PWM_CNT 1
#define MX_PWM_TRIS1 trisc
#define MX_PWM_1 5

//Functions
#include <system.h>
#pragma CLOCK_FREQ 4000000

//Configuration data
#pragma DATA 0x2007, 0x30c4

//Internal functions
#include "C:\Flowcode V4\FCD\internals.h"

//Macro function declarations
void FCM_Operation();


//Variable declarations
short FCV_REDGREEN;
char FCV_FLASHER;
short FCV_AMBERRED;
short FCV_RSLT;


//Defines:

/**** Macro Substitutions ****
1 = Which ADC Channel
40 = Acquisition time
3 = Conversion Speed
0 = VRef+ Option
500 = VRef Voltage x 0.01V
******************************/




//ADC0: //Macro function declarations

void FCD_ADC0_SampleADC();
char FCD_ADC0_ReadAsByte();
short FCD_ADC0_ReadAsInt();
float FCD_ADC0_ReadAsVoltage();
void FCD_ADC0_ReadAsString(char* FCR_RETVAL, char FCR_RETVAL_SIZE, char NumBytes);



//ADC0: //Macro implementations


void FCD_ADC0_SampleADC()
{
    
    /*******Supported Devices******************************************************************
    // 16F616, 16F676, 16F677, 16F684, 16F685, 16F687, 16F688, 16F689, 16F690
    ******************************************************************************************/

        #define MX_ADC_CHANNEL        1
        #define MX_ADC_SAMP_TIME     40
        #define MX_ADC_CONV_SP        3
        #define MX_ADC_VREF_OPT        0

        //set up ADC conversion
        char old_tris, cnt;

        //assign conversion rate
        adcon1 = ((MX_ADC_CONV_SP & 0x07) << 4);

        //find appropriate bit
        #if (MX_ADC_CHANNEL == 0)
            #define MX_ADC_TRIS_REG  trisa
            #define MX_ADC_TRIS_MSK  0x01
            ansel = 0x01;
        #endif
        #if (MX_ADC_CHANNEL == 1)
            #define MX_ADC_TRIS_REG  trisa
            #define MX_ADC_TRIS_MSK  0x02
            ansel = 0x02;
            #if (MX_ADC_VREF_OPT == 1)
                #pragma error "Target device is currently using AN1 for VREF+"
            #endif
        #endif
        #if (MX_ADC_CHANNEL == 2)
            #define MX_ADC_TRIS_REG  trisa
            #define MX_ADC_TRIS_MSK  0x04
            ansel = 0x04;
        #endif
        #if (MX_ADC_CHANNEL == 3)
            #define MX_ADC_TRIS_REG  trisa
            #define MX_ADC_TRIS_MSK  0x10
            ansel = 0x08;
        #endif
        #if (MX_ADC_CHANNEL == 4)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x01
            ansel = 0x10;
        #endif
        #if (MX_ADC_CHANNEL == 5)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x02
            ansel = 0x20;
        #endif
        #if (MX_ADC_CHANNEL == 6)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x04
            ansel = 0x40;
        #endif
        #if (MX_ADC_CHANNEL == 7)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x08
            ansel = 0x80;
        #endif
        #if (MX_ADC_CHANNEL == 8)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x40
            anselh = 0x01;
        #endif
        #if (MX_ADC_CHANNEL == 9)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x80
            anselh = 0x02;
        #endif
        #if (MX_ADC_CHANNEL == 10)
            #define MX_ADC_TRIS_REG  trisb
            #define MX_ADC_TRIS_MSK  0x10
            anselh = 0x04;
        #endif
        #if (MX_ADC_CHANNEL == 11)
            #define MX_ADC_TRIS_REG  trisb
            #define MX_ADC_TRIS_MSK  0x20
            anselh = 0x08;
        #endif

        //sanity check
        #ifndef MX_ADC_TRIS_REG
            #pragma error "ADC Type 3 conversion code error - please contact technical support"
        #endif

        //store old tris value, and set the i/o pin as an input
        old_tris = MX_ADC_TRIS_REG;
        MX_ADC_TRIS_REG = MX_ADC_TRIS_REG | MX_ADC_TRIS_MSK;

        //turn ADC on
        adcon0 = 0x01 | (MX_ADC_CHANNEL << 2);

        //assign VREF functionality
        #if (MX_ADC_VREF_OPT == 1)
            set_bit(adcon0, VCFG);
        #endif

        //wait the acquisition time
        cnt = 0;
        while (cnt < MX_ADC_SAMP_TIME) cnt++;

        //begin conversion and wait until it has finished
        adcon0 = adcon0 | 0x02;
        while (adcon0 & 0x02);

        //restore old tris value, and reset adc registers
        MX_ADC_TRIS_REG = old_tris;
        ansel = 0x00;
        adcon0 = 0x00;

        #if(anselh)
            anselh = 0x00;
        #endif

        #undef MX_ADC_TRIS_REG
        #undef MX_ADC_TRIS_MSK
        #undef MX_ADC_SAMP_TIME
        #undef MX_ADC_CHANNEL
        #undef MX_ADC_CONV_SP
        #undef MX_ADC_VREF_OPT

}

char FCD_ADC0_ReadAsByte()
{
    
        FCD_ADC0_SampleADC();

        return adresh;

}

short FCD_ADC0_ReadAsInt()
{
    
        short iRetVal;

        FCD_ADC0_SampleADC();

        iRetVal = (adresh << 2);
        iRetVal = iRetVal | (adresl >> 6);

        return (iRetVal);

}

float FCD_ADC0_ReadAsVoltage()
{
    

        int iSample;
        float fSample, fVoltage, fVperDiv;

        #define MX_ADC_VREF_V        500

        iSample = FCD_ADC0_ReadAsInt();                                            //Read as 10-bit Integer

        fVoltage = float32_from_int32(MX_ADC_VREF_V);                    //Convert reference voltage count to floating point (0 - 500 x 10mV)
        fVoltage = float32_mul(fVoltage, 0.01);                            //Convert reference voltage count to actual voltage (0 - 5)
        fVperDiv = float32_mul(fVoltage, 0.000976);                        //Convert actual voltage to voltage per division (VRef / 1024)
        fSample = float32_from_int32(iSample);                            //Convert to floating point variable
        fVoltage = float32_mul(fSample, fVperDiv);                        //Calculate floating point voltage

        #undef MX_ADC_VREF_V
        return (fVoltage);

}

void FCD_ADC0_ReadAsString(char* FCR_RETVAL, char FCR_RETVAL_SIZE, char NumBytes)
{
    
        float fVoltage;

        if (NumBytes > FCR_RETVAL_SIZE)
            NumBytes = FCR_RETVAL_SIZE;

        fVoltage = FCD_ADC0_ReadAsVoltage();
        FCI_FLOAT_TO_STRING(fVoltage, 2, FCR_RETVAL, NumBytes);    //Convert to String

}

//Macro implementations

void FCM_Operation()
{
    //Main Branch of Traffic Light Operation
    
    //Call Component Macro
    //Call Component Macro: rslt=ADC(0)::ReadAsInt
    FCV_RSLT = FCD_ADC0_ReadAsInt();


    //Timing Calculations
    //Calculation:
    //  RedGreen = 1+((rslt+1)/17)
    //  AmberRed = RedGreen/2
    FCV_REDGREEN = 1+((FCV_RSLT+1)/17);
    FCV_AMBERRED = FCV_REDGREEN/2;
    

    //Delay
    //Delay: 30 ms
    delay_ms(30);


    //N/S Red E/W Green
    //Output: 0x21 -> PORT C
    trisc = 0x00;
    portc = 0x21;


    //Delay
    //Delay: RedGreen s
    delay_s(FCV_REDGREEN);


    //N/S Red E/W Amber
    //Output: 0x11 -> PORT C
    trisc = 0x00;
    portc = 0x11;


    //Delay
    //Delay: AmberRed s
    delay_s(FCV_AMBERRED);


    //N/S Green E/W Red
    //Output: 0x0c -> PORT C
    trisc = 0x00;
    portc = 0x0c;


    //Delay
    //Delay: RedGreen s
    delay_s(FCV_REDGREEN);


    //N/S Amber E/W Red
    //Output: 0x0A -> PORT C
    trisc = 0x00;
    portc = 0x0A;


    //Delay
    //Delay: AmberRed s
    delay_s(FCV_AMBERRED);


}

void main()
{
    
    //Initialisation
    ansel = 0;
anselh = 0;


    //Interrupt initialisation code
    option_reg = 0xC0;


    //Loop
    //Loop: While 1
    while (1)
    {
        //Input
        //Input: A0 -> Flasher
        trisa = trisa | 0x01;
        FCV_FLASHER = ((porta & 0x01) == 0x01);


        //Decision
        //Decision: Flasher > 0?
        if (FCV_FLASHER > 0)
        {
            //Comment:
            //When Flasher switch is high, This subroutine flashes the N/S Amber and
            //the E/W Red with a 1 second delay


            //Output
            //Output: 0x11 -> PORT C
            trisc = 0x00;
            portc = 0x11;


            //Delay
            //Delay: 1 s
            delay_s(1);


            //Output
            //Output: 0 -> PORT C
            trisc = 0x00;
            portc = 0;


            //Delay
            //Delay: 1 s
            delay_s(1);


        } else {
            //Call Macro
            //Call Macro: Operation
            FCM_Operation();


        }


        if ((1) == 0) break;
    }


    mainendloop: goto mainendloop;
}

void interrupt(void)
{
}
 

Attachments

edeca

Active Member
Good work skeeter, nice to see flowcode working for you. Let's see some action shots too!
 

skeeterb

Member
I've tweaked the formula to calculate the timing for the delays. The new formula is ((rslt+1)/17). Now it has a 0 to 60 second delay for the Red/Green timing, and half of that for the Amber/Red delay.
 

skeeterb

Member
here is my new code since I added the left turn signals to my code

Code:
//************************************************************************************
//**  
//**  File name:     C:\temp\Traffic Light.c
//**  Generated by:  Flowcode v4.0.0.53
//**  Date:          Wednesday, July 01, 2009 09:33:33
//**  Licence:       Demo
//**  
//**        ***DEMO VERSION***
//**  
//**  
//**     NOT FOR COMMERCIAL USE
//**  
//**  http://www.matrixmultimedia.com
//************************************************************************************


#define MX_PIC

//Defines for microcontroller
#define P16F690
#define MX_EE
#define MX_EE_SIZE 256
#define MX_SPI
#define MX_SPI_BCB
#define MX_SPI_SDI 4
#define MX_SPI_SDO 7
#define MX_SPI_SCK 6
#define MX_UART
#define MX_UART_B
#define MX_UART_TX 7
#define MX_UART_RX 5
#define MX_I2C
#define MX_MI2C
#define MX_I2C_B
#define MX_I2C_SDA 4
#define MX_I2C_SCL 6
#define MX_PWM
#define MX_PWM_CNT 1
#define MX_PWM_TRIS1 trisc
#define MX_PWM_1 5

//Functions
#include <system.h>
#pragma CLOCK_FREQ 4000000

//Configuration data
#pragma DATA 0x2007, 0x30c4

//Internal functions
#include "C:\Flowcode V4\FCD\internals.h"

//Macro function declarations
void FCM_Operation();
void FCM_LeftTurn();


//Variable declarations
short FCV_REDGREEN;
char FCV_TIMEOUT;
char FCV_FLASHER;
short FCV_AMBERRED;
short FCV_RSLT;


//Defines:

/**** Macro Substitutions ****
1 = Which ADC Channel
40 = Acquisition time
3 = Conversion Speed
0 = VRef+ Option
500 = VRef Voltage x 0.01V
******************************/




//ADC0: //Macro function declarations

void FCD_ADC0_SampleADC();
char FCD_ADC0_ReadAsByte();
short FCD_ADC0_ReadAsInt();
float FCD_ADC0_ReadAsVoltage();
void FCD_ADC0_ReadAsString(char* FCR_RETVAL, char FCR_RETVAL_SIZE, char NumBytes);



//ADC0: //Macro implementations


void FCD_ADC0_SampleADC()
{
    
    /*******Supported Devices******************************************************************
    // 16F616, 16F676, 16F677, 16F684, 16F685, 16F687, 16F688, 16F689, 16F690
    ******************************************************************************************/

        #define MX_ADC_CHANNEL        1
        #define MX_ADC_SAMP_TIME     40
        #define MX_ADC_CONV_SP        3
        #define MX_ADC_VREF_OPT        0

        //set up ADC conversion
        char old_tris, cnt;

        //assign conversion rate
        adcon1 = ((MX_ADC_CONV_SP & 0x07) << 4);

        //find appropriate bit
        #if (MX_ADC_CHANNEL == 0)
            #define MX_ADC_TRIS_REG  trisa
            #define MX_ADC_TRIS_MSK  0x01
            ansel = 0x01;
        #endif
        #if (MX_ADC_CHANNEL == 1)
            #define MX_ADC_TRIS_REG  trisa
            #define MX_ADC_TRIS_MSK  0x02
            ansel = 0x02;
            #if (MX_ADC_VREF_OPT == 1)
                #pragma error "Target device is currently using AN1 for VREF+"
            #endif
        #endif
        #if (MX_ADC_CHANNEL == 2)
            #define MX_ADC_TRIS_REG  trisa
            #define MX_ADC_TRIS_MSK  0x04
            ansel = 0x04;
        #endif
        #if (MX_ADC_CHANNEL == 3)
            #define MX_ADC_TRIS_REG  trisa
            #define MX_ADC_TRIS_MSK  0x10
            ansel = 0x08;
        #endif
        #if (MX_ADC_CHANNEL == 4)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x01
            ansel = 0x10;
        #endif
        #if (MX_ADC_CHANNEL == 5)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x02
            ansel = 0x20;
        #endif
        #if (MX_ADC_CHANNEL == 6)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x04
            ansel = 0x40;
        #endif
        #if (MX_ADC_CHANNEL == 7)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x08
            ansel = 0x80;
        #endif
        #if (MX_ADC_CHANNEL == 8)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x40
            anselh = 0x01;
        #endif
        #if (MX_ADC_CHANNEL == 9)
            #define MX_ADC_TRIS_REG  trisc
            #define MX_ADC_TRIS_MSK  0x80
            anselh = 0x02;
        #endif
        #if (MX_ADC_CHANNEL == 10)
            #define MX_ADC_TRIS_REG  trisb
            #define MX_ADC_TRIS_MSK  0x10
            anselh = 0x04;
        #endif
        #if (MX_ADC_CHANNEL == 11)
            #define MX_ADC_TRIS_REG  trisb
            #define MX_ADC_TRIS_MSK  0x20
            anselh = 0x08;
        #endif

        //sanity check
        #ifndef MX_ADC_TRIS_REG
            #pragma error "ADC Type 3 conversion code error - please contact technical support"
        #endif

        //store old tris value, and set the i/o pin as an input
        old_tris = MX_ADC_TRIS_REG;
        MX_ADC_TRIS_REG = MX_ADC_TRIS_REG | MX_ADC_TRIS_MSK;

        //turn ADC on
        adcon0 = 0x01 | (MX_ADC_CHANNEL << 2);

        //assign VREF functionality
        #if (MX_ADC_VREF_OPT == 1)
            set_bit(adcon0, VCFG);
        #endif

        //wait the acquisition time
        cnt = 0;
        while (cnt < MX_ADC_SAMP_TIME) cnt++;

        //begin conversion and wait until it has finished
        adcon0 = adcon0 | 0x02;
        while (adcon0 & 0x02);

        //restore old tris value, and reset adc registers
        MX_ADC_TRIS_REG = old_tris;
        ansel = 0x00;
        adcon0 = 0x00;

        #if(anselh)
            anselh = 0x00;
        #endif

        #undef MX_ADC_TRIS_REG
        #undef MX_ADC_TRIS_MSK
        #undef MX_ADC_SAMP_TIME
        #undef MX_ADC_CHANNEL
        #undef MX_ADC_CONV_SP
        #undef MX_ADC_VREF_OPT

}

char FCD_ADC0_ReadAsByte()
{
    
        FCD_ADC0_SampleADC();

        return adresh;

}

short FCD_ADC0_ReadAsInt()
{
    
        short iRetVal;

        FCD_ADC0_SampleADC();

        iRetVal = (adresh << 2);
        iRetVal = iRetVal | (adresl >> 6);

        return (iRetVal);

}

float FCD_ADC0_ReadAsVoltage()
{
    

        int iSample;
        float fSample, fVoltage, fVperDiv;

        #define MX_ADC_VREF_V        500

        iSample = FCD_ADC0_ReadAsInt();                                            //Read as 10-bit Integer

        fVoltage = float32_from_int32(MX_ADC_VREF_V);                    //Convert reference voltage count to floating point (0 - 500 x 10mV)
        fVoltage = float32_mul(fVoltage, 0.01);                            //Convert reference voltage count to actual voltage (0 - 5)
        fVperDiv = float32_mul(fVoltage, 0.000976);                        //Convert actual voltage to voltage per division (VRef / 1024)
        fSample = float32_from_int32(iSample);                            //Convert to floating point variable
        fVoltage = float32_mul(fSample, fVperDiv);                        //Calculate floating point voltage

        #undef MX_ADC_VREF_V
        return (fVoltage);

}

void FCD_ADC0_ReadAsString(char* FCR_RETVAL, char FCR_RETVAL_SIZE, char NumBytes)
{
    
        float fVoltage;

        if (NumBytes > FCR_RETVAL_SIZE)
            NumBytes = FCR_RETVAL_SIZE;

        fVoltage = FCD_ADC0_ReadAsVoltage();
        FCI_FLOAT_TO_STRING(fVoltage, 2, FCR_RETVAL, NumBytes);    //Convert to String

}

//Macro implementations

void FCM_Operation()
{
    //Main Branch of Traffic Light Operation
    
    //Output
    //Output: 0x21 -> PORT C
    trisc = 0x00;
    portc = 0x21;


    //Delay
    //Delay: RedGreen s
    delay_s(FCV_REDGREEN);


    //Output
    //Output: 0x11 -> PORT C
    trisc = 0x00;
    portc = 0x11;


    //Delay
    //Delay: AmberRed s
    delay_s(FCV_AMBERRED);


    //Output
    //Output: 0x09 -> PORT C
    trisc = 0x00;
    portc = 0x09;


    //Delay
    //Delay: RedGreen s
    delay_s(FCV_REDGREEN);


    //Call Macro
    //Call Macro: LeftTurn
    FCM_LeftTurn();


    //Output
    //Output: 0x0C -> PORT C
    trisc = 0x00;
    portc = 0x0C;


    //Delay
    //Delay: RedGreen s
    delay_s(FCV_REDGREEN);


    //Output
    //Output: 0x0A -> PORT C
    trisc = 0x00;
    portc = 0x0A;


    //Delay
    //Delay: AmberRed s
    delay_s(FCV_AMBERRED);


    //Output
    //Output: 0x09 -> PORT C
    trisc = 0x00;
    portc = 0x09;


    //Calculation
    //Calculation:
    //  Timeout = 1
    FCV_TIMEOUT = 1;
    

    //Delay
    //Delay: RedGreen s
    delay_s(FCV_REDGREEN);


    //Call Macro
    //Call Macro: LeftTurn
    FCM_LeftTurn();


}

void FCM_LeftTurn()
{
    
    //Decision
    //Decision: Timeout>0?
    if (FCV_TIMEOUT>0)
    {
        //Output
        //Output: 0x80 -> PORT B
        trisb = 0x00;
        portb = 0x80;


        //Delay
        //Delay: AmberRed s
        delay_s(FCV_AMBERRED);


        //Output
        //Output: 0x40 -> PORT B
        trisb = 0x00;
        portb = 0x40;


        //Delay
        //Delay: AmberRed s
        delay_s(FCV_AMBERRED);


        //Output
        //Output: 0 -> PORT B
        trisb = 0x00;
        portb = 0;


    } else {
        //Output
        //Output: 0x20 -> PORT B
        trisb = 0x00;
        portb = 0x20;


        //Delay
        //Delay: AmberRed s
        delay_s(FCV_AMBERRED);


        //Output
        //Output: 0x10 -> PORT B
        trisb = 0x00;
        portb = 0x10;


        //Delay
        //Delay: AmberRed s
        delay_s(FCV_AMBERRED);


        //Output
        //Output: 0 -> PORT B
        trisb = 0x00;
        portb = 0;


    }


    //Calculation
    //Calculation:
    //  Timeout = 0
    FCV_TIMEOUT = 0;
    

    //Delay
    //Delay: 5 s
    delay_s(5);


}

void main()
{
    
    //Initialisation
    ansel = 0;
anselh = 0;


    //Interrupt initialisation code
    option_reg = 0xC0;


    //Loop
    //Loop: While 1
    while (1)
    {
        //Call Component Macro
        //Call Component Macro: rslt=ADC(0)::ReadAsInt
        FCV_RSLT = FCD_ADC0_ReadAsInt();


        //Calculation
        //Calculation:
        //  RedGreen = ((rslt+1)/17)
        //  AmberRed = RedGreen/2
        FCV_REDGREEN = ((FCV_RSLT+1)/17);
        FCV_AMBERRED = FCV_REDGREEN/2;
        

        //Input
        //Input: A0 -> Flasher
        trisa = trisa | 0x01;
        FCV_FLASHER = ((porta & 0x01) == 0x01);


        //Decision
        //Decision: Flasher > 0?
        if (FCV_FLASHER > 0)
        {
            //Comment:
            //When Flasher switch is high, This subroutine flashes the N/S Amber and
            //the E/W Red with a 1 second delay


            //Output
            //Output: 0x11 -> PORT C
            trisc = 0x00;
            portc = 0x11;


            //Delay
            //Delay: 1 s
            delay_s(1);


            //Output
            //Output: 0 -> PORT C
            trisc = 0x00;
            portc = 0;


            //Delay
            //Delay: 1 s
            delay_s(1);


        } else {
            //Call Macro
            //Call Macro: Operation
            FCM_Operation();


        }


        if ((1) == 0) break;
    }


    mainendloop: goto mainendloop;
}

void interrupt(void)
{
}
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top