Skip to content

EmbeddedSystemClass/Truck_Project1

Repository files navigation

Truck_Project1


Truck_Project1 is an automotive SCADA system which uses a Xilinx Spartan-3E to monitor real-time data,
a STM32F100RB to handle a keypad and route message traffic, and a TS-7200/7800 to do I/O (turning on and
off lights and reading switches). The STM32F100RB (STM32) will route message traffic to and from the FPGA, the
TS-7200 and handle the keypad input.


A Windows 10 TCP client runs on a laptop and the VGA port is connected to an external 8" monitor in the dash as
the UI.

Because the fact that the STM32 has no ethernet connection, and only communicates with the TS-7200 via a serial port,
the message passing gets really complicated. Add to that, the fact that I want to be able to send messages using the
keypad as well as the Windows client to the TS-7200.

Using the keypad

The keypad buttons, for now, do the basic functions I need:
  • '1' - start engine
  • '2' - stop engine
  • '3' - brights
  • '4' - cooling fan
  • '5' - heater blower
  • '6' - running lights
  • '7' - headlamps
  • '8' - wipers
  • '9' - not used
  • '0' - not used
  • Note: when you press '1' to start the engine, it only powers the relays for the ignition, fuel pump, and completes a
    circuit to a button on the dash to power the starter solinoid. Then, the code in the TS-7200 only gives you 10 seconds
    to start the engine. After that, the starter solinoid is disabled. The 'stop engine' button (2) will turn off the ignition
    and fuel pump. (Now that you know how to start my truck, please don't take it. I guess I need a password dialog.)
    The keys: A->D navigate the bottom 10 buttons on the windows client starting with 'Start Engine' going down to
    'Settings Three', then up to 'Play List' and then down to 'Settings Four'. The system will operate without the laptop,
    but you can only use the numbered buttons on the keypad. The messages generated by the lettered buttons are routed to the
    Windows client The buttons labeled 'Test Ports', 'Settings One/Two/Three/Four' call up child dialogs that
    send messages to the TS-7200. The text on the button and the message it sends can be edited by changing xml files.

    The STM32 processor

    The STM32F100RB is in the subdirectory 'STM32' and was generated using STM32CubeMX and compiled with TrueStudio.
    The project uses FreeRTOS as the operating system. Currently, all but 3 pins are used so the next step is to upgrade
    to a better STM32 chip. I added some user code in the gpio.c file that added the pins for the 2 DS1620's. There are
    sections in the generated code that are reserved for user editing. Anything outside these sections gets removed if you
    pull the project back into CubeMX. I had to do it this way because the data pin on the DS1620 is changed from input to
    output. One of the routines generated is a callback for a 1 second timer which reads the DS1620's to turn the cooling
    fan on or off according to what the DS1620 for engine temp reads. (The DS1620 is mounted on the thermostat housing).
    The other DS1620 is in the cab and reads the indoor temp. A section in the timer callback turns on/off the blower for the
    heater depending on the indoor temp.

    The Xilinx processor

    I use a Spartan-3E Xilinx FPGA board to monitor real-time data like engine RPM,MPH. It sends data to the STM32
    over a parallel port. The STM32 sends data to the FPGA board over a RS-232 port and uses handshaking signal.
    Two sensors are connected to the FPGA board which are converted to RPM/MPH readings. One sensor comes from a
    hall-effect switch on the driveshaft and another comes from a light sensor on the crankshaft. The FPGA also
    gets messages from the STM32 to generate DTMF tones whenever the keys on the keypad are pushed. The data from
    the RPM/MPH is sent over a parallel port to the STM32 which sends it on to the client and also sent to an XMEGA
    processor over a serial line which drives two LCD displays mounted on the dash.

    The IO box (TS-7200)

    I'm using a TS-7200 embedded linux card from Technologic which has a PC-104 card connector. (shown on left)
    The card runs linux compiled for the ARM processor on the card. When it gets powered up, it automatically
    starts an app called 'sched' which uses POSIX threads and runs as a TCP/IP server. The ethernet port is
    extended to an RJ-45 socket on the outside of the box where the cross-over cable plugs into.
    The picture on the right shows the 2 PC-104 IO cards mounted on top of it. Each card has 20 input and output
    ports; The outputs are the small 5A relays, 10 on each side, and the inputs come from the grey ribbon cable.
    The outputs of the small 5A relays go to other 10A relays which control low voltage 12Vdc circuits like the
    running lights and blinkers, while the higher amperage circuits like the headlights and starter solinoid are
    controlled by 10-30A cube relays. The serial port next to the ethernet port goes to the STM32. So there is no
    way to upload a new sched program to the iobox because on the bench, I have to ftp into it from another linux
    desktop. When it's in the vehicle, I have to use a Windows app called 'SendFiles' which makes a TCP/IP connection
    to the linux server after the sched program exits with a special code. There is another ARM compiled program
    on the linux server called 'server' which downloads the new sched program from the SendFiles program running
    on the client. After downloading, the system is rebooted. This is all handled by a bash script in the sched
    directory called 'try_sched.sh' which gets called when the linux card boots up. So if I make a change to the
    client where the message list is different and try to run it before uploading the new sched, I have to pull
    it in the garage and move a linux desktop inside and ftp into it.
    There is also a 2 line LCD screen (not shown) on the iobox that scrolls the messages that come to the sched.

    The AVR/LCD screen

    I originally was using a t6963 LCD screen with an AVR Pro-Mini on the back of it which got serial commands
    from UART2 of the STM32 and sent them to the LCD screen's parallel port. I was trying to do some kind of user
    input from the keypad which got too problematic so I went to using the Windows laptop as the UI. This is not
    show on the system diagram at the top, but I will have to, at some point re-install it when I start running out
    of room to display RT data on the Windows screen. All the code for the AVR processor is in the AVR_t6963
    directory. At one time I had a PWM signal coming from the FPGA board which would dim the LCD screen.

    The Home Server

    I'm currently working on another Windows C# app which works just like the client, only it's a TCP
    server which runs on the desktop in the garage and only works when the truck is parked just outside.
    There are 2 network connections on the client. One is threw an ethernet cross-over cable plugged
    directly into the TS-7200 iobox and the other is a WiFi connection. When I start the client app
    on the laptop, I have to connect to the TS-7200 using the top-left button shown as 'Disconnect'.
    (The text for this button says 'Connect Server' when not connected to linux server, or 'Disconnect
    when connected). Then I can close the lid on the laptop, put it under the seat and use the keypad to
    navigate the 10 buttons on the bottom. The button called 'Call Home' will connect to the Home Server
    and then I can go back in the garage and while the engine is warming up, set config parameters
    and control the lights, blower and shut off the engine for what it's worth. (Also monitor the temps).
    The picture shows the home server on the lower-right and the status window of the client (running on my desktop)
    on the upper-left. The blue window on the upper-right is just a tty connected to an extra comm port
    on the TS-7200 which just shows debug messages. The messages scrolling on the edit boxes are from
    clicking on the buttons on the home server. The main purpose of the home server is to set configuration
    parameters which get saved to a file on the TS-7200.

    Configuration Parameters

    The 3 buttons on the lower-right of the home server are used to manage the configuration parameters.
    The 'Get Params' button gets the parameters from the param.conf file which stores the params on disk(TS-7200).
    The 'Config Params' button pulls up a dialog (show above) on the home server where the user can modify the
    params. The 'Upload Params' button loads the params needed by the STM32 to control the cooling and heater fan.
    Namely, the temperatures on the left. There is also a way to set the params on the Windows client.

    List of config params on TS-7200

  • rpm_update_rate
  • mph_update_rate
  • fpga_xmit_rate
  • high_rev_limit
  • low_rev_limit
  • cooling_fan_on
  • cooling_fan_off
  • blower_enabled
  • blower1_on
  • blower2_on
  • blower3_on
  • lights_on_delay
  • engine_temp_limit
  • batt_box_temp
  • test_bank
  • The update rates are not implemented yet, but will control how fast the RPM/MPH data is sent to the displays.
    The high/low rev limit are for the rev limiter.
    The cooling fan on/off determine at what engine temps the cooling fan goes on or off. Hopefully the fan on is higher
    than the fan off.
    The blower_enabled is the engine temp at which the STM32 even responds to the indoor temps to control the heater.
    The blower1_on is the highest indoor temp at which the blower runs on low speed.
    The blower2_on is the medium speed temperature.
    The blower3_on is the highest speed temperature.
    So the blower will come on high speed when the indoor temp is below what the blower3_on temp is set to.
    The blower will switch to medium speed when the indoor temp reaches blower2_on temp, and will switch to
    low speed when the indoor temp is between blower1_on and blower2_on, and finally go off when above blower1_on.
    The lights on delay is how many seconds the lights/running lights stay on after the engine shuts off.
    The TS-7200 actually uses this value to also shut off the blower motor too.
    The engine_temp_limit is the engine temperature at which an alarm sounds. Currently the engine doesn't shut
    down at too high a temp, but at some point in the future it should, along with the oil pressure which isn't hooked up yet.
    The battery box temp is for the heat strip underneath the battery which is behind the passenger seat.

    More about the Windows Client

    The buttons labeled: 'Test Ports', 'Settings One/Two/Three/Four' call up a child dialog which works the same with
    the A->D keys on the keypad as they do on the main screen of the client screen. 'A' moves up, 'B' moves down, '*' moves
    to the opposite column, 'C' executes whatever the key applies to, and 'D' closes or exits. Each button on the main
    screen are assigned an xml file, so I can edit the name of each button on the child dialog and what it does as far as
    what message it passes to the linux server. So the 3rd button down on the right labeled 'Lights On/Off' will toggle the
    headlights on and off. There is another type of child dialog that is set by xml files which is a scrolling list of values
    to choose from. Most of the scrolling list dialogs are used to set the config parameters.

    More on the IO box (TS-7200)

    The sched program starts with a command line param called odata.dat which is a database of all the io settings.
    There are 40 records in the database. Currently the fields for each record are:
  • port
  • onoff
  • input_port
  • type
  • time_delay
  • label

  • The label field is:
  • STARTER
  • ACCON
  • FUELPUMP
  • COOLINGFAN
  • LHEADLAMP
  • RHEADLAMP
  • RUNNINGLIGHTS
  • LIGHTBAR
  • LEFTRBLINKER
  • RIGHTRBLINKER
  • LEFTFBLINKER
  • RIGHTFBLINKER
  • LBRAKELIGHT
  • RBRAKELIGHT
  • XLBLINKER
  • XRBLINKER
  • LBRIGHTS
  • RBRIGHTS
  • HTRBLOWERLOW
  • HTRBLOWERMED
  • HTRBLOWERHIGH
  • WWIPER1
  • WWIPER2
  • (rest not used)
    The port is always 0->39, the onoff is not used, the input_port is the input that applies to the output,
    for instance, the input types for LHEADLAMP and RHEADLAMP are 0 because the switch to turn the headlights
    on is connected to the 1st input port on the first IO card. The type determines how the output behaves
    when it's activated.
  • 0) regular - on/off state responds to assigned input (affected_output)
  • 1) goes on/off and stays that way until another on/off
  • 2) on for time_delay seconds and then it goes back off
  • 3) goes on/off every second until time_delay is up
  • 4) if on, turn off and wait for msg (serial or tcp) to turn back on
  • 6) goes on/off at pulse_time rate in 10ths of a second then goes off when time_delay is up
  • 7) goes on/off at pulse_rate in 10ths of a second if onoff is active only
  • (type 6 & 7 not implemented yet)
    The time_delay only applies to types 2 & 3 (used by blinkers).
    Notice I have an output assigned to (4) blinkers. The reason for this stems from the fact that on most older
    vehicles, the tail light bulb works for both the brakes and blinkers. I had to do a special work-around by
    adding 2 outputs called XLBLINKER and XRBLINKER.

    The type for the 4 blinkers are 3 and the type for the 2 Xblinkers are type 2. So when the brakes are applied
    and one of the blinkers is on, the blinker will still work. (Hope that explains it).

    mingetty & try_sched.sh

    (Warning: not for the faint of heart)
    I had to compile a c program called mingetty.c for the ARM compiler which can be downloaded online.
    Then I had to modify some files in the /etc directory.
    The directory in /etc/rc.d has the directories: rc0.d->rc6.d which have bash scripts which gets executed
    in order when linux boots.

    the directory: rc.d/rc3.d has links to startup scripts in /etc/init.d

    Then in /etc/init.d, I place 'my_startup.sh which is just a switch/case statement with 'start' and 'stop'
    Under 'start' it just does:
    cd /home/dan/dev/sched # change directory to where the try_sched.sh gets executed
    ./try_sched.sh # execute the try_sched.sh script
    'my_startup.sh':
    This script is in /etc/init.d

    What this does is, everytime the linux card is turned on or rebooted, try_sched.sh get executed.
    echo "running try_sched.sh (v1.14)" >> status.txt
    date >> status.txt
    if [ ! -e /mnt/cf/temp.txt ]
    then
     ../mountcf.sh
     echo "mounting cf"
    fi
    
    if [ -e /root/sched ]
    then
     mv /root/sched sched
     chmod +x sched
     echo "new sched found in /root" >> status.txt
    
    else if [ -e sched2 ]
    then
     mv sched2 sched
     chmod +x sched
     echo "new sched found (sched2)" >> status.txt
    else
     echo "using current sched" >> status.txt
    fi
    fi
    
    ./sched odata.dat
    OUT=$?
    echo "OUT:" >> status.txt
    echo $OUT >> status.txt
    date >> status.txt
    
    if [ $OUT -eq 1 ]
     then
      echo "exit to shell" >> status.txt
    fi
    
    if [ $OUT -eq 2 ]
     then
      echo "rebooting from script" >> status.txt
     /sbin/reboot
    fi 
    
    if [ $OUT -eq 3 ]
     then
      echo "shutdown from script" >> status.txt
    /sbin/shutdown -h now
    fi
    
    if [ $OUT -eq 4 ]
     then
      echo "downloading new try_sched.sh" >> status.txt
      ./server >> status.txt
      ./sched2 test 1
      OUT=$?
    
    if [ $OUT -eq 10 ]
      then
       echo "download ok" >> status.txt
       mv sched2 sched
       chmod +x sched
       /sbin/reboot
    else 
     echo "bad download" >> status.txt
      rm sched2
      /sbin/reboot
    fi
    fi
    
    if [ $OUT -eq 141 ]
     then
      echo "rebooting from 141" >> status.txt
    fi
    
    if [ $OUT -eq 139 ]
     then
      echo "rebooting from 139" >> status.txt
    fi
    

    What this does is first, it mounts the flash drive if the file 'temp.txt' exists.
    Then, it checks to see if sched is in /root, moves it to the current directory, sets the exec flag
    and the goes to the './sched odata.dat which executes the sched program.
    If there is not sched in root, it checks to see if there is a 'sched2' in the current directory
    and changes the name to sched, sets the execute flag and executes it. The 'sched2' is what gets
    uploaded by the 'SendFiles' and server program when the client exits with a code '4'.

    if [ $OUT -eq 4 ]
     then
      echo "downloading new try_sched.sh" >> status.txt
      ./server >> status.txt
      ./sched2 test 1
      OUT=$?
    

    There is a few lines of code in the very beginning of the sched program that checks if there were
    3 command line params passed to it:

    else if(argc == 3)
    {
    	if((strcmp(argv[1],"test") == 0))
    	{
    		printf("testing\r\n");
    	}
    	printf("%s\r\n",argv[1]);
    	return 10;
    }
    

    The 2nd one being the string: 'test'. This way, we can check to see if a valid sched has been uploaded.
    Otherwise, it goes to 'bad download', deletes the sched2 and reboots. If the sched returns a code '10'
    when the 'test' string is passed in, it means the file is valid so it renames sched2 to sched, sets the
    execute flag and reboots.
    The other exit codes pertain to what happens when you go to the 'Manage Server' button on the top left
    of the client screen.
    The 'Reboot Server' button tells the sched program to exit with a code '2', The 'Shutdown' button tells
    the sched to exit with a code '3' and the 'Upload New' button makes the sched exit with a '4'.
    (Exit to Shell will just make the sched quit and if you are not hooked up to comm1 with a tty,
    then you're out of luck, and will have to do a reset.)
    At the very end of 'sched.c', when the program exits, a global variable called: 'reboot_on_exit' gets set
    to the exit code sent by the client:

    	if(reboot_on_exit == 1)
    	{
    //		printf("sched: exit to shell\r\n");
    		return 1;
    	}
    	else if(reboot_on_exit == 2)
    	{
    //		printf("sched: reboot\r\n");
    
    		return 2;
    	}
    	else if(reboot_on_exit == 3)
    	{
    //		printf("sched: shutdown\r\n");
    		return 3;
    	}
    	else if(reboot_on_exit == 4)
    	{
    //		printf("doing upload new\r\n");
    		return 4;
    	}
    

    Some highlights of sched

    The thread_io directory has all the files used to compile the sched program. The 'Makefile' uses the ARM
    cross-compiler to compile for the particular ARM processor the TS-7200 uses. The 3 main c files are:
    sched,c tasks.c and cmd_tasks. The sched.c file is where the 'main()' function is and creates some POSIX
    threads specified in 'tasks.h':
    enum task_types
    {
    	GET_HOST_CMD,
    	MONITOR_INPUTS,
    	MONITOR_INPUTS2,
    	TIMER,
    	TIMER2,
    	BUTTONS,
    	TCP_MONITOR,
    	SERIAL_RECV,
    	BASIC_CONTROLS
    } TASK_TYPES;
    

    The function for the GET_HOST_CMD thread is in cmd_tasks,c and is a huge switch/case that gets messages
    from the TCP connection. If the Windows client is not connected, this section gets skipped over.
    The other tasks are in tasks.c.
    The MONITOR_INPUTS task just waits for something to change on the input ports of the IO cards.
    The MONITOR_INPUTS2 task is a way to programmatically inject 'fake inputs' to the system so it thinks
    the input ports have changed. The TIMER_TASK is a task that gets called once a second. The SERIAL_RECV
    task gets command from the STM32. The BASIC_CONTROLS task waits on a queue for messages and controls
    the output ports.

    Wiring for the relays

    The box on the left is the TS-7200 card with the IO daughtercards and the 5A relays. These have a common
    ground and power the primary relay modules with 5vdc.

    You can buy these real cheap off of ebay (read: China). Since they are rated at 10A, I can use some of
    to power small amperage appliances, like the blinkers or brake lights. Others, like the headlamps,
    are on a separate 10 or 30A cube relay. I don't have the secondary battery anymore. I did that originally
    because I was afraid of voltage spikes, which are not a problem. Plus, I have a voltage supressor
    across the battery terminals. So the common 12v fed to the primary relays comes from the main 12v car
    battery. I do, howerver, have another car battery behind the passenger seat to power an inverter to
    make 110vac to power the laptop and the 9vdc adapter for the 8" monitor, and in the future, a backup
    cam and speakers for the laptop to play music or other mp3 files. I have a small battery charger hooked
    up to the 2nd car battery. The reason I had to use a 2nd car battery is the inverter craps out when running
    off the 12vdc input from the alternator - just too high a voltage. There is a 110v plug at the back of the
    truck which, in addition to the battery charger, runs a heat strip under the batteries, and runs a block
    heater on the engine block to keep it warm in the winter.

    Misc.

    I didn't mention, but the 'Play List' button on the client screen brings up a scrolling list of wav files
    on the laptop that play.

    I should also mention that the buttons on the client screen: 'Reboot Server', 'Show Params', 'Home Server'
    and 'Set Srv Params' will be changed in the future. They are just for testing now.

    About

    An automotive SCADA system using 4 different processors

    Resources

    Stars

    Watchers

    Forks

    Releases

    No releases published

    Packages

    No packages published