View previous topic :: View next topic |
Author |
Message |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
header.h files |
Posted: Mon May 18, 2020 11:21 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Mon May 18, 2020 12:08 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon May 18, 2020 2:50 pm |
|
|
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
......
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Mon May 18, 2020 11:44 pm |
|
|
The problem is you show a little 'bit' of your include file, not everything.
Understand.
If I have:
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](images/smiles/icon_sad.gif) |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Tue May 19, 2020 8:18 am |
|
|
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; //
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Tue May 19, 2020 8:52 am |
|
|
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.. |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Tue May 19, 2020 9:48 am |
|
|
Thanks Ttelmah.
You may have explained some other problems I'm seeing.
I will go over my code carefully. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Wed May 20, 2020 2:04 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Wed May 20, 2020 4:35 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Thu May 21, 2020 9:29 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Thu May 21, 2020 10:24 am |
|
|
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 ! |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Fri May 22, 2020 8:03 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Fri May 22, 2020 8:09 am |
|
|
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](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Fri May 22, 2020 8:18 am |
|
|
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](images/smiles/icon_lol.gif) |
|
![](templates/subSilver/images/spacer.gif) |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Fri May 22, 2020 9:44 am |
|
|
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] |
|
![](templates/subSilver/images/spacer.gif) |
|