element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum Hi, I need some hellp with my code structure.
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Verified Answer
  • Replies 38 replies
  • Subscribers 384 subscribers
  • Views 5036 views
  • Users 0 members are here
Related

Hi, I need some hellp with my code structure.

phoenixcomm
phoenixcomm over 2 years ago

for you that don't know I grew up writing C code. So my Code Base has multiple files currently working on my Landing Gear for my sim. 

I have the following files in the LandingGear directory:
LandingGear.ino
isr1.c through isr5.c 
lamps.c 
and landingGear.h

so in lamps.c  i have my code for the lamp test. 

void lampTest( int state ){
for( int count = 0; count < 10; count++;) {
digitalWrite( Lamps.pin[count] ); }
}

it is called from isr4 (isr4.c)

it is also  declared in landingGear.h


#define TRUE 1
#define FALSE -1
#define ON 1
#define OFF 0

/************************** Prototypes *****************************/

void lampTest( int state );
void lamp( Lamps.pin[count], int state );
void blink( Lamps.pin[count] );

typedef struct Lamps{
char name[];
char name[];
lamp} Lamps[] = {
{22, "RIGHT", "RED"}, {23, "NOSE", "RED"}, {24, "LEFT", "RED"},
{25, "RIGHT", "GREEN"}, {26, "NOSE", "GREEN"}, {27, "LEFT", "GREEN"},
{28, "WARNnose", "GREEN"}, {29, "WARNgear, "ORANGE"}, {30, "WARNnoseDis, "BLUE"}, {31, "WARNskid", "RED"}};

and pucks with this isr4.c:2:12: error: ‘ON’ undeclared (first use in this function)    lampTest( ON );

cam anybody give me a straight answer why this happens???

~~  thanks C Harrison

  • Sign in to reply
  • Cancel

Top Replies

  • shabaz
    shabaz over 2 years ago +8
    Hi Cris, The following rules extremely strong guidelines I think apply to your specific scenarios: (1) For every .c file apart from main.c, create a header file with the same name. Otherwise, it's…
  • shabaz
    shabaz over 2 years ago in reply to phoenixcomm +5
    Hi Cris, This is what's causing the problems, because there will be corner-cases (sometimes more often than not) where things will break down and not compile (as you have seen) unless those guidelines…
  • ntewinkel
    ntewinkel over 2 years ago in reply to shabaz +3
    What shabaz said ^ It can be tempting to cut corners by skipping coding best practices, but then you often run into issues that cost you so much more time and frustration later.
Parents
  • shabaz
    0 shabaz over 2 years ago

    Hi Cris,

    The following rules extremely strong guidelines I think apply to your specific scenarios:

    (1) For every .c file apart from main.c, create a header file with the same name. Otherwise, it's extremely confusing, and causes the types of issues that you are seeing. So, for lamps.c, there should also be a lamps.h; anything else is definitely unorthodox. The same name header file (with .c replaced with .h) is the standard way. If you feel that will result in too many files for your volume of code, then that's a sign that you may have too many source files, e.g. all lamp related functions may be better in a single file than several (this is just an example).

    (2) For every header file, stick in there the function prototypes, that you want to be accessible elsewhere. So, your lamps.h file should contain void lampTest( int state ); and your lamps.c file should not contain this prototype.

    (3) Each .c file should contain a #include with the same name header file. So, your lamps.c file should contain #include lamps.h

    (4) Each header file should contain something like the following:

    #ifndef __LAMPS_HEADER_FILE__
    #define __LAMPS_HEADER_FILE__
    /* the rest of the file */
    #endif // __LAMPS_HEADER_FILE__

    This too is standard, always to be done without question. If it isn't done, then it's again extremely unorthodox.

    (5) Now you are free to liberally use #include "lamps.h" in any file you like. There's no issue with excessively using it, because the linker will only use it once, regardless of how many places it is included, so you're not bloating the firmware. For readability, sure it should only be used where needed. So, your main code will contain #include "lamps.h" and you will be free to use the lampTest function in the main function.

    (6) Absolutely important (same level as feeding gremlins after midnight! this is defcon 1 level): Never define variables in your header files. Always in .c source files, otherwise again it's in unorthodox territory where it will sometimes work but will often cause issues. If you need to access that variable from a different file (for instance, if (say) you have a lampState variable defined in lamps.c that you also wish to use in main.c, then you must use an extern declaration, and ideally in the header file. So, your lamps.h file would contain extern int lampState; and then your main.c file needs to contain nothing except the #include "lamps.h".

    There are plenty of other guidelines, but the ones above are most directly related to the types of symptoms you are seeing, and it's a guaranteed approach. The concepts are solid.

    If you want to be sure that any of the above is normal, it's good to examine trusted code, for example peek at the Linux source code, e.g. this header file. You'll see examples of extern in there for instance, but you could browse other files from that link too, to follow how others coded it.

    By the way, there may be "more standard" ways to do things (for instance, there are conventions on naming of things, which I have not followed above, since I'm not a C developer (any more). Also, there are more modern techniques, for instance, the C++ concept of setters and getters reduces the need to share variables across files, and such concepts can be coded in C too. But that's for another day.

    Finally, if you upload your code to (say) replit, then others can inspect and optionally edit your code (if you give them permission : ). 

    • Cancel
    • Vote Up +8 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • ntewinkel
    0 ntewinkel over 2 years ago in reply to shabaz

    What shabaz  said ^  Smile cat

    It can be tempting to cut corners by skipping coding best practices, but then you often run into issues that cost you so much more time and frustration later.

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • ggabe
    0 ggabe over 2 years ago in reply to ntewinkel

    Often times the boilerplate code is boring. Good news: you can ask ChatGpt to write your headers, then write a skeleton C implementation file as well. Can be recruited for other tasks, like writing functional code as well. 

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • michaelkellett
    0 michaelkellett over 2 years ago in reply to ntewinkel

    It all pays off in the end.

    I use a very similar structure to that suggested by Shabaz (although I've been told that I shouldn't use the double or single underline as a prefix to #defines in my application code).

    One pay off is that I have been able to write a cloning programme which can refactor complete projects changing the root name of all the files and include file protectors etc.

    so my files are all names:

    project_description.c (or .h)

    project will usually be something like alarm_clock, alclk  etc  - a project name abbreviation

    description is an abbreviated description of the purpose of the file (module).

    SO the source file folder for a project looks like:

    image

    The root file name for this project is dctrl

    and it can be cloned like this:

    image

    The cloner is very Keil MDK specific and modifies the Keil IDE files as well as the source  files.

    Every file gets an cloner generated internal header like this:


    //
    //       FILE: dctrl_project.h
    //  COPYRIGHT: 2022 MK Electronics Ltd
    //
    //     AUTHOR: MK
    //       DATE: 06/10/2022
    //     ORIGIN: New
    //
    //    PROJECT: OLED and LCD Display Controller
    //   HARDWARE: GD32E103C8
    // TOOL CHAIN: KEIL
    //
    
    // Define to prevent recursive inclusion 
    
    #ifndef DCTRL_PROJECT_H
    #define DCTRL_PROJECT_H
    

    It takes out some of the hassle of the boilerplate code.

    MK

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Reply
  • michaelkellett
    0 michaelkellett over 2 years ago in reply to ntewinkel

    It all pays off in the end.

    I use a very similar structure to that suggested by Shabaz (although I've been told that I shouldn't use the double or single underline as a prefix to #defines in my application code).

    One pay off is that I have been able to write a cloning programme which can refactor complete projects changing the root name of all the files and include file protectors etc.

    so my files are all names:

    project_description.c (or .h)

    project will usually be something like alarm_clock, alclk  etc  - a project name abbreviation

    description is an abbreviated description of the purpose of the file (module).

    SO the source file folder for a project looks like:

    image

    The root file name for this project is dctrl

    and it can be cloned like this:

    image

    The cloner is very Keil MDK specific and modifies the Keil IDE files as well as the source  files.

    Every file gets an cloner generated internal header like this:


    //
    //       FILE: dctrl_project.h
    //  COPYRIGHT: 2022 MK Electronics Ltd
    //
    //     AUTHOR: MK
    //       DATE: 06/10/2022
    //     ORIGIN: New
    //
    //    PROJECT: OLED and LCD Display Controller
    //   HARDWARE: GD32E103C8
    // TOOL CHAIN: KEIL
    //
    
    // Define to prevent recursive inclusion 
    
    #ifndef DCTRL_PROJECT_H
    #define DCTRL_PROJECT_H
    

    It takes out some of the hassle of the boilerplate code.

    MK

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Children
  • shabaz
    0 shabaz over 2 years ago in reply to michaelkellett

    Hi Michael,

    Nice idea to have helper programs etc to set up projects!

    I just saw this in GNU documentation, which confirms the definition naming convention that you mention. And finally discovered the name for it from that link; the whole #ifndef.. #ifdef thing is called a "Once-Only Header".

    image 

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • phoenixcomm
    0 phoenixcomm over 2 years ago in reply to michaelkellett

     michaelkellett using #_name should be NEVER used as this is RESERVED for the OS!  This will bite you in your ass!!

    ~~ CAH

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • phoenixcomm
    0 phoenixcomm over 2 years ago in reply to michaelkellett

     michaelkellett yes when I use Eclipse for C or Java I get  this

    /*  Author C. A. Harrison
     *  Date: July 29, 2023
     *  Licence: (This depends on the project)
     *  Name: Landing Gear System
     *  REV: -
     *  IDE: Ecipse x.xx toolchain: GNU GCC
     *
     *  file: landingGear.c
    */ 

    All I did was set it in my prefrenss. 

    and normally my programs are set up in my REPO

    something like this: (this is for NexGen-j)

    public/NexGen-J/Aircraft/ Electrical
    Engines
    FireSystem
    LandingSystem
          bin
          src
                Arduino
                       LandingSystem
                             LandingSystem.ino
                             isr1.c
                             isr2.c
                             isr3.c
                             isr4.c
                             isr5.c
                            lamps.c
                            include
                                        defs.h
                                        isr1.h
                                        isr2.h
                                        isr3.h
                                         isr4.h
                                         isr5.h
                                         lamps.h
                                         landingGear.h
                 java
                       LandingSystem.java

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube