CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

header.h files

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

header.h files
PostPosted: Mon May 18, 2020 11:21 am     Reply with quote

How do I declare a global variable in a header file?
I placed
Code:
    char statusA, statusB = 0;         // status bits               
    long status_flags = 0;             // status flags

assuming they would be global variables but when my program stopped working I realized they were local to MAIN() only.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon May 18, 2020 12:08 pm     Reply with quote

Depends where you are loading the file.

If the file is included before the main, and are not inside a function
in the include file, then the variables will be global.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Mon May 18, 2020 2:50 pm     Reply with quote

The variables are to be used in a function called by MAIN and also used in MAIN.
The function does not see them. This is part of the header file:
Code:
Console.h
// Global Variables
    char statusA = 0;                      // status bits               
// Function prototypes
    void fault_disp(void);                 // display faults


The function prototype is in the .h file in the order shown above. Is the order the problem and if that is the case how would I differentiate between global and local variables in the .h file? (If I remove the // before char statusA=0; in the code below the program works, but not as shown above in the .h file)
The relevant parts of the program are:

Code:
 #include <16F887.H>
 #include "Console.h"
....
//    char statusA = 0;                      // status bits 
MAIN()
...
// use statusA
...
fault_disp();       // uses StatusA
......
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon May 18, 2020 11:44 pm     Reply with quote

The problem is you show a little 'bit' of your include file, not everything.

Understand.
If I have:
Code:

char fred;


and put this in an include file, provided this is loaded before the code, this
variable will be global.

However if I have:
Code:

void func(void)
{
    char fred;
}


and put this in an include file, and load it as before, then 'fred' is a local
variable to the function 'func'. Not global.

In C, a variable _declared outside the functions_, is always global.
Variables have to be declared before they are used (not true in all C's,
and not true now in CCS for variables declared inside functions).

So, what you show, should make statusA global, _provided this is not
inside a function definition
_.

Also understand that a local variable will always have precedence over
a global variable. So:
Code:


char fred=1;

void main(void)
{
    char fred=2;

    printf("Fred is %d", fred);
 
    while (TRUE)
       ;
}


Will print 'Fred is 2". The local variable has taken precedence over the
global one. So being careful over your variable names is important.
This latter, might be why you are having problems... Sad
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Tue May 19, 2020 8:18 am     Reply with quote

I understand where to declare Global variables in a program but how does the include file tell the program WHAT they are.
This is my entire include file:
Code:
//////////////////////////////////////////////////////////////////////////////////////////
// CONTROL CONSOLE HEADER FILE     File  Console PIC_1_v1.0.h                            //
// Last modified:   29 June 2017                                                        //
//////////////////////////////////////////////////////////////////////////////////////////

// define I2C address
 #define consolePIC_2_WRT_ADDR  0X10      // Console slave PIC 2
 #define consolePIC_2_READ_ADDR 0x11
 #define SERVO_WRT_ADDR         0X12      // Rud & Elev servo PIC
 #define SERVO_READ_ADDR        0x13
 #define SIDE_WRT_ADDR          0X14      // Side thrusters PIC
 #define SIDE_READ_ADDR         0x15
 #define ROTATE_WRT_ADDR        0X16      // Thruster Rotate PIC
 #define ROTATE_READ_ADDR       0x17
 #define GRIP_WRT_ADDR          0X18      // Gripper Pod PIC
 #define GRIP_READ_ADDR         0x19
 #define FOREARM_WRT_ADDR       0X1A      // Forearm PIC
 #define FOREARM_READ_ADDR      0x1B
 #define ARM_WRT_ADDR           0X1C      // Upper Arm PIC
 #define ARM_READ_ADDR          0x1D
 #define BASE_WRT_ADDR          0X1E      // Manipulator Base PIC
 #define BASE_READ_ADDR         0x1F
 #define LCD_1                  0x40      // LCD 1 0x20
 #define LCD_2                  0x42      // LCD 2 0x21
 #define LCD_3                  0x44      // LCD 3 0x22
 #define LCD_default            0x4e      // default LCD address
 #define CMPS11_wrt             0xc0      // Compass write address
 #define CMPS11_read            0xc1      // Compass read address

// constants
 #define buff_size 22                    // characters per line plus one

// Global Variables
    char LCD_WRT_ADDR = 0X40;                      // set to first LCD, 0x4e default
    short timeout_error = 0;                       // for timed get_c()
    short polarity = 1;                            // pol_adj dir, 1=pos, 0=neg
    char statusA, statusB = 0;          // status bits               
    long status_flags = 0;              // status flags

// Function prototypes
    void fault_disp(void);           // display faults
    void init_LCD(char which_LCD, char *buff);     // initialize LCD
//    char read&pack_sws(void);
    char timed_getc (void);                        // get RS232 character, timed
    char polarity_adj (byte raw_data);             // get abs value & polarity
    char add_offset (byte raw_data, byte offset);
    char subtract_offset (byte raw_data, byte offset);
    void clear_LCD (void);                         // Clear LCD
    void cursor(short ctrl);                       // Turn cursor ON(1) or OFF(0)
    void ctrl_start (int ctrl);                    // Turn Start Screen ON or OFF
    void control_addr (short ctrl);                // Turn on mode
    void set_I2C_addr (char addr);                 // set the I2C address, 7 bit
    void chipset_config (char ctrl);               // 0=ST7920, 1,3,4=KS0108, 2=ST7565
    void text_position (int line, int column);     // set start for next text
    void set_font (char size);                     // set font size
    void set_DM(char cmd);                         // set Display Mode for next command
    void send_str(char *buff);                     // Send string to LCD
    void draw_line(int x, int y, int x1, int y1);  // draw a line from x,y to x1,y1
    void beep(void);                               // beep for 100 ms

The include is at the start of my program and statusA is used in a function but is not seen by it. The only change to make it work is to remove the definitions from the include file and place them before MAIN. Below is the relevant part of my program showing my Global variables placed where they do work. The dotted lines are other code that is not relevant (many pages).
Code:
/* Pre-processor directives */
 #include <16F887.H>
 #include <math.h>
 #include "Console PIC_1_v1.0.h"
 #fuses INTRC_IO, NOWDT, PUT, NOPROTECT, BROWNOUT, MCLR, NOLVP
 #use delay (clock=8000000)
...........
// Function prototypes see Console PIC_1_v1.0.h
// Global variables. These do not work in the .h file
    char LCD_WRT_ADDR = 0X40;                      // set to first LCD, 0x4e default
    short timeout_error = 0;                       // for timed get_c()
    short polarity = 1;                            // pol_adj dir, 1=pos, 0=neg
    char statusA, statusB = 0;         // status bits               
    long status_flags = 0;             // status flags

// ***************The main function*********************
void main(void)
 {
..................
// declare local variables
  int i,j = 0;
  float volts  = 0;             // ROV Battery Voltage to 0
  float amps   = 127;           // ROV Battery Current to 0
  char rudd_abs =0;             // rudder absolute value
.................
// ******************************* loop continuously ***************************************
while (1)
 {                                          // Complete Loop including LCDs
// ** read switches and pack into variables, invert as required so select = true **
  switch_1 = (((input_e() & 0x03))<<6) | (input_a() & 0x3F);
............................
   fault_disp();                // call fault display function
...........................
 }                        // end of while loop
}                       // end of main function

// ********** Functions **********
// function 'fault_disp' handles the displays in LCD2
// LCD is 21 characters by 7 lines
   void fault_disp(void)    // display faults
{
  long status = 0;
  char buff[10];                // variable array buff
  int posn, line, item = 0;     // variables

// update status
   status = ((status | statusB)<<8)|statusA;  //
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue May 19, 2020 8:52 am     Reply with quote

It doesn't. It is completely dependant on where the file is included.

Get into the habit of using the traditional (originally required) C syntax of
defining all variables at the start of the function. Makes it easier to avoid
accidental re-use of a name in the code.
Also avoid using variable type names like 'long'. This has different meanings
dependant on the compiler involved. Result can be disaster. Use explicit
names like int8, int16 etc..
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Tue May 19, 2020 9:48 am     Reply with quote

Thanks Ttelmah.
You may have explained some other problems I'm seeing.
I will go over my code carefully.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed May 20, 2020 2:04 am     Reply with quote

Yes.
These is another issue that could cause problems:
Code:

 #include <16F887.H>
 #fuses INTRC_IO, NOWDT, PUT, NOPROTECT, BROWNOUT, MCLR, NOLVP
 #use delay (clock=8000000)
 //move these to here
 #include <math.h>
 #include "Console PIC_1_v1.0.h"

If the prototypes in the 'Console', do anything involving timings, there
can be problems if these are before the 'clock' setup.
However the variables here should be global, and I can't see any
variable redeclarations that might cause issues.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed May 20, 2020 4:35 am     Reply with quote

Just a 'code comment'..
I see float for both volts and amps.
PICs are not really 'floating point processors' and take a LOT of time to do FP math. Running a PIC at 8MHz doesn't help either.
You'll see a tremendous improvement if you use 'scaled integers', easily 10-20x faster and smalle codespace required.
Once you get your current problem fixed, you should search 'scaled integers' here and see how they're done.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Thu May 21, 2020 9:29 am     Reply with quote

Ttelmah and Temtronic thanks for the help. I try to keep my questions simple but cannot include all my software or details. Here is why:
My home-made ROV has a main thruster with rudder and elevator to control the stern. It has two rotating side thrusters that control climb and dive and assist in turns by their speed and direction. All of these are coupled in software and controlled by a single joystick. It has lights, a camera, pitch and roll sensors, a compass, and a depth sensor.
The ROV is on a 300ft tether and data is transferred bi-directionally on a twisted pair from a PIC in the control console to a PIC in the ROV so timing is critical. However motors and servos can take from a millisecond to over a second to get where they are supposed to go so I use distributed processing to avoid messing up communications.
The master PICs in the Console and ROV use slave PICs on I2C to do the slow stuff. The Console PIC sends a stream of commands to the ROV PIC that immediately replies with status information (RS485). The ROV PIC then sends, by I2C, the commands to three other PICs that control the three thruster motors, the two side thruster rotate motors, and the rudder and elevator servos.
The system worked well for several years in wire-wrap form but additions dictated a re-build of the control console and a new set of PCBs for the ROV. This complete re-design introduced new problems such as PICs that no longer worked (yes, in the errata which I now check carefully).
It is now working again and ready for water testing in a few weeks. My next addition is a robotic arm which is built and working except I am struggling to get it to neutral buoyancy which is absolutely required. I am starting on a new project of a scanning sonar to see through the murk in the Ottawa River. I invite anyone interested in collaborating to contact me.
You and others on this forum have been of immense help in the past for which I am very grateful. I will have to try some of your observations on test programs, especially the ‘scaled integers’, but for now everything is working so it will have to wait. Thanks again.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu May 21, 2020 10:24 am     Reply with quote

gee wirewrap ?? i thought I was the only one left with that stuff in the drawers !!!
The Ottawa river's 'murky' from what the politicians have been adding to it over the years....

hope it's sunny up there, I'm still wondering what the yellow thing in the blue sky is down here !
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Fri May 22, 2020 8:03 am     Reply with quote

Yes, wire wrap as below.
[img]https://www.dropbox.com/s/ywk3ud7dz84kt1q/Top TrayWW.jpg?dl=0[/img]
here is the PCB replacement. I made separate PCB to be modular and they can be used for other projects. There are ten PCB altogether. The original four motor driver L298/L6203 boards were retained.
[img]https://www.dropbox.com/s/zothptv32hkukpq/Top Tray_fix.jpg?dl=0[/img]
This is the control console
[img]https://www.dropbox.com/s/fk793qpyzx17950/New monitor.jpg?dl=0[/img]
and this is the ROV
[img]https://www.dropbox.com/s/fvnacg871xtw8gt/ROV in Pool.JPG?dl=0[/img]
I'm not sure if these will show or if I am inserting pictures correctly.
Edit: OK I don't know what I'm doing. You will have to copy and paste the links.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri May 22, 2020 8:09 am     Reply with quote

I must admit I still have a wirewrap tool, some sockets, and wire, but I
haven't used them for ages, except as a source of some thin insulated solid
core wire...
Having paid quite a lot of money for a LPKF PCB prototyping system,
I tend to just make boards for everything now. Very Happy
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri May 22, 2020 8:18 am     Reply with quote

Guess it's a real good thing the above ground pool blew out last faLL AND NOT REPLACED. The last thing I need is to build an ROV..but.. main that is nice.
You'll need a tow-behind battery pack and lighting 'trailer' for the ottawa though Laughing
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Fri May 22, 2020 9:44 am     Reply with quote

I send 200v DC down and convert it in the ROV for unlimited running. It does not care if there is 20v line drop but I have to limit the current draw in the switcher or there will be runaway (less voltage>more current>less voltage).
The battery is a 12v LiFePO4 and I had to add 7lbs when I replaced the Gel with it. The motors all run off 24v DC from a switching power supply.
My biggest problem is the sun so I want to use FPV (First person View) goggles used for RC airplanes. The 19" monitor is nice for looking at the recordings after an outing and indoors. It slides into a slot on the back of the monitor so is easily lifted off. I used to use an 8mm VCR seen below with the robotic arm.
https://www.dropbox.com/s/wqodofzldrnyfr9/Arm%20%26%20New%20Console.JPG?dl=0
In case that does not work I will add the link as before. Dropbox does not seem to care about the full link.
[img]https://www.dropbox.com/s/wqodofzldrnyfr9/Arm%20%26%20New%20Console.JPG?dl=0[/img]
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group