element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • 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
Personal Blogs
  • Community Hub
  • More
Personal Blogs
NexGen Flight Simuator NexGen: Software Development: arduino sketch & eclipse on Linux. Part 2
  • Blog
  • Documents
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: phoenixcomm
  • Date Created: 29 Jun 2018 2:27 PM Date Created
  • Views 950 views
  • Likes 8 likes
  • Comments 9 comments
  • nexgen
  • avr
  • software development
  • and no-nos
  • arduino_tutorials
  • eclipse ide
  • programing
  • goto
  • arduino
Related
Recommended

NexGen: Software Development: arduino sketch & eclipse on Linux. Part 2

phoenixcomm
phoenixcomm
29 Jun 2018

Ok now the fun stuff. Now we can do something..  We still have a small mess to clean up now. It's the Arduino's Libraries. They are quite a mess so here is what we have to do
The Arduino's IDE wants only to see two main functions:

  • setup()  Setup is where you do something once.
  • loop()  Loop is just that a loop. Now while in the loop() function you may call other functions. A function is nothing more than a subroutine, with a defined argument list, or none, and some return type or void for nothing.

Most of the time when I write software in almost any language with the exception of Perl, my code looks like this (ANSI C):

#include main.h

#include stdio.h

int main (int argc, char *argv[]) {

int errorcode = housekeeping();

if( errorcode) => 1) {

// this is my function that has the initialization code or what you would put in the Arduino's sketch.

// the # sign includes my personal header file with defines, pin defines etc.

// the # sign include stdio is to load the standard IO lib which lets me use printf.

// the first function I call is main() which is the mandatory entry point for user input commands etc.

// Now function I call is housekeeping () in its own file and companion header ie. (housekeeping.c and housekeeping.h

// why doesn't it have a return type on housekeeping well its formally described in its two files and it has an int return type (something might have failed) so my return is 0 which is reverse logic.  Please don't panic any return with a 1 or higher means well are done. Or if you really want to, make them negative numbers. )(purist)

NOTE: NEVER EVER do error checking as shown below in the table (the program was on "Stack Exchange" voted the correct way of using a GOTO LOL) (just don't use the damn thing.)

// the reasoning is that as your program gets larger and larger you wish to hide code from some other parts. This is part of the scoping rules
// here you can implement a case statement to print out the errorcode you don't have to go look it up.

printf( "Huston we have a problem: %d \n", errorcode); }

else {

Now about my style, I know I'm going to get jumped but what the hell, but here goes. (I and the universe hates blank space its a vacuum.)

  • Between a ) and { as in for, while, if, function call, etc. there is always 1 space. NOT a new line with the curly brace on a newline.
  • To end a { with a }: the closing curly brace is on the last line of the function, etc.  NOT a new line with the curly brace on a newline. (if you like it please use a heavily typed language like Python or Ada. 
  • example:

errorcode( int n) {

    if ( something ) {

          switch errornumber {

              case 1 {

                    I'm dead;

                  break; }  // always use the break so your code doesn't fall through. 

              case 2 {

                    Your dead;

                    break; // better for me!! } Please Note this will NOT work as the comment is before  }

              defualt {

                    Someone else died!; }}}}  //Please always use a default case!!

Please note the last line with the 4 closing curly braces I much prefer it to this silliness.

                  default

                                {

                                Someone else died!;

                                }

                            }

                      }

                  } 

Organization Each one of your functions should have its own file.c and file.h remember the header is where you will define your function. So your usage of your function anywhere must agree with it's declaration in the header file (.h). Now an easy way to include all the headers that your software needs to be seen is just included them in a header file. yup a header file containing other header files. (what a concept)

So for instance, if your program uses both the I2C and TCP. The way I encapsulate this is very simple. The software never calls either directly as there are no public header files; as there are no public header files included. what I have done is included 6 functions setup_I2C, setup_TCP, read_I2C, read_TCP, write_I2C, write_TCP. And yes I also have to write an interrupt handler as well. Please note my capitalization. The only reason that TCP and I2C are capped is that they are protocol names and normally capped.

NOTHING IS CAPED except #define as in #define TRUE 1; or structure names which I normally cap the first letter.

 

Oh yes, flower-ism. Please avoid these things which other programming languages try to enforce, ie PASCAL, you have to use a pointer -> to basically dereference something. Like fred->car.color  which is very simple which is the color of Fred's car; right? So please refrain from using flower-isms like this: FredpointstoCarColor -> Car.Color image.

This nonsense gets worse in Java with their crazy Cap No Cap Cap and No Cap. This all gets carried to its logical conclusion by our friends the French who came up with a set of rules (guidelines) of how to write a program. No nothing to do with logic. it is MISRA. they have over 144 rules. Unfortunately, the FAA and Uncle Sam loves MISRA and there is a complete set of dah rules published in the JSF Coding Standard. I believe that I have a lint with the rules built into it.[2]image

NEVER DO THIS:DON'T DO THIS:

void foo()
{
  
if (!doA())
  
goto exit;
  
if (!doB())
  
goto cleanupA;
  
if (!doC())
  
goto cleanupB;

  
/* everything has succeeded */

   return;
cleanupB:
  undoB
();
leanupA
:
  undoA
();
exit:
  
return;
}

*** 2  returns, Very Bad. image

*** conditions !doB and !doC never tested

also his name conventions are not the same between function and Cleanup

 

here I moved doA to the bottom, As to allow testing of B & C

void foo() {
   if( !doB()) {
      undoA(); }
    else if (!doC()) {
      undoB(); }
    else if(!doA()) {
       return;
    else {  //

now what are you going to do?

MAYBE THIS: NOPE But CloseTHIS WILL WORK

void foo() {
if (!doA() && !doB() && !doC(){ return; }

 

The following is still wrong what happens when do C fails??

void foo() {

   if (!doB()) {

      undoA(); }

   else if (!doC(){

      undoB(); }

   else if (!doA() && !doB() && !doC() {

      return; }}

First fix doA(), doB() and doC()

they now return (ERROR) // simple #define ERROR -1

now we can do this intelligently.

#define PASS 1;

void foo() {

int A, B, C = PASS; // assign them all to PASS

if (( B = doB()) == ERROR ){

    undoA(); }

else if(( C = doC()) == ERROR ){

    undoB(); }

else if(( A = doA()) == ERROR ){

   // do something!!

else{

// ::= !A + !B + !C   WINER WINER CHICKEN DINNER

   return;

}

 

Naming Conventions: Never start anything with a number, or an underscore (reserved for OS calls) Never use the world or prefix my this is a holdover from Perl and Pascal - Just don't.[1]

 

Only one more thing TAB vs WHITESPACE

you can do whichever you prefer BUT a tab is not a tab on every system is it 2, 4, 8 spaces. So the moral is if your code is only seen by your eyes than its up to you. But If your code will be seen on other eyes on other systems, then use white space in that way the next guy who sees your code does not have to reformat it. image

 

Go Build something.

 

 

 

 

 

 

 

 

 

Revision History: (most are underlined)

  • Comment in Naming Conventions and the usage of my
  • Added info on JSF Coding Standard.
  • Added table with hated goto
  • in the last table fixed missing ) in if tests
  • I added a better expanation of both main() and the includes
  • Sign in to reply

Top Comments

  • phoenixcomm
    phoenixcomm over 6 years ago in reply to mcb1 +2
    Mark, I started with a "DeSmet C" Compiler on a pc with DOS back in 80 something while I was in College. It was broke and I found out the hard way in a compiler class with the Dragon Book. It was a nice…
  • genebren
    genebren over 6 years ago +2
    Coding and code formatting is a lot like religion. Everybody has their own ideas on what is right and wrong and will defend their views with the greatest of energy. I have long since learned to let people…
  • mcb1
    mcb1 over 6 years ago +1
    phoenixcomm I'm not sure what you're referring to in this line It's the Arduino's Libraries. They are quite a mess The later version seem to dump the libraries in the user space (well they do in windows…
  • mcb1
    mcb1 over 6 years ago in reply to phoenixcomm

    Not really sure what you meant by:

    When I first viewed it is was squashed up like someone had grabbed it and reduced the entire size by 25%... but either something changed in Chrome or the site changed it, but it looked much better.

     

    That error messaging sounds like a great way to quickly identify the issues.

    Far better than having to run a debug, etc in the hope of grabbing whatever caused it.

     

    Cheers

    Mark

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • phoenixcomm
    phoenixcomm over 6 years ago in reply to mcb1

    Mark

    Not really sure what you meant by:

    Hey what happened white space appeared above.??

    Is it Chrome (which has trouble with some pages) or did you do some tweaking.?

    Man I love error message, NexGen has just one book devoted to error messages. All of the errors are reported by three numbers SS:UN:xxxx. Where SS=Subsystem, UN=UnitNumber, and then the Error Message Number itself. I use printf to print them and therefore can use any separator character.  I only have one function that just printing error numbers to the log.

    This is an oversimplified version of my error module, in fact, it quite involved, as they also have a system timestamp and other information,  depending on the subsystem. for instance the NAV error portion has a timestamp,  frame number (major and minor) Accelerations Axises (pitch, roll, yaw),  altitude, Aircraft Mass (changes with fuel, etc), and of course the ERROR itself, this helps to debug the NAVbus without the use of the use of computer that is used as an RMON probe and then looking at SNMT (good luck) 

    error_message( int SS, int UN, int item ) {

         // retrieve error message from DB

         char *message = grab_error_message( SS, UN, item );

         FILE *elfp;   // grab a file pointer, and named it ErrorLogFP

         fp = freopen("log.txt","w+", stdout);/p>

         printf( "%d:%d:%d --- %s \n", SS, UN, item, *message); }

     

    flags are just a bombs waiting to go off.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • phoenixcomm
    phoenixcomm over 6 years ago in reply to genebren

    Gene, don't get me wrong. I use both end-of-line and comment blocks. I also use blank lines to help as well.

    here is a keyboard controler. with all the notes, but the big picture is not here it is in the support document which shows this as a state machine.

     

    NOTE: Gene Don't check this for correctness It might have a number of errors in it. This CRAZY EDITOR!? took out all of the F** white spaces~~~ Woopie but look at and you'll get the idea. Yes, It reads like a book.  But you have to understand that my code never stands alone. I only write it after I understand what it has to do. that's why I have my SUPPORT DOCUMENT, by Sub-System. I have an entire book about 50 pages just on this one chunk of hardware. this is part of this: Figure 3-1. Compute-Display Unit CP-1252/ASN-128 controls/indicators.

    Not only does my document have the pilots "how to use this thing" but I also have a "theory of operation" and the "major software modules" in the unit.

    then you have to deal with the diplay (which shows you DMS, as well as MilGrid mode), and all of the communications between head, Arduino(s) and host(IOP), and listening to messages from the NAV - MODEL @ 100fps which tells you where you are.

     

     

    /*

    * keyboard.c

    *

    * Jul 12, 2012, Harrison Creation

    * Sep 19, 2013, P.Zilber now the keyboard is handled by keyboard and not cdu_read

    * Nov 25, 2013, Harrison implemented the above and added special key processing here.

    *

    */

    #include "cdu.h"

    #include "navbox.h"

    #include "keyboard.h"

    #include "keyboard_data.h"

     

     

    void keyboard( struct cdu_s * cdu, char datum ) {

         switch(datum) {

              // Now we check the keyboard for special keys

              // defines are in keyboard.h

              case ENT:{

                   eol();

                   break; }

              case CLR:{

                   clear();

                   break; }

              case KYBD:{

                   kybd();

                   break; }

              case TGT:{

                   target();

                   break; }

              default:{

                   // this must be a valid key

                   switch( format[cdu->display_cntl][cdu->cursor] ) {

                        case 'A':{

                             switch( cdu->keystroke ) {

                                  case 0: {

                                       cdu->alpha_low = datum;   

                                       cdu->keystroke ++;

                                       // write nop to the display

                                       nop( cdu );

                                       break; }

                                  case 1: {

                                       cdu->alpha_high = datum;

                                      cdu->ascii_char = alpha[cdu->alpha_high][cdu->alpha_low];

                                       // write to the display & update cursor

                                       cdu_write( cdu );

                                       // reset the alpha keystroke counter

                                       cdu->keystroke = 0;

                                       cdu->cursor++;

                                       break; }}

                                  break; }

                        case 'N': {

                             // now all thats left is ASCII numbers

                             // write to the display & update cursor

                             cdu_write( cdu );

                             cdu->cursor++;

                             break; }

                        default: {

                             // TBE ERROR

                             break; }}}}

    }

     

     

    /*

    * The following functions are for special keys

    *

    * eol() just like the return key it tells the iop what the msg is.

    * target() TBD

    * clear() instructs the display to clear ie backspace 1 char or clear the display under program control.

    * kybd()  changes the display under program control.

    *

    */

    void eol( struct cdu_s * cdu ) {

         // transmit to host

         cdu->display_cntl = -1;

         cdu->keyboard_cntl = -1;

         keyboard_power( OFF );

         update( ON ); }

     

    void target( struct cdu_s * cdu ) {

    // TBD

    }

     

    void clear( struct cdu_s * cdu ) {

         switch( cdu->clear_flag ){

              case 0: {

                   cdu->clear_flag++;

                   // clear char under cursor control

                   break; }

              case 1 : {

                   cdu->clear_flag = 0;

                   // clear display under program control

                   break; }}}

     

     

    void kybd( struct cdu_s * cdu ) {

         update( OFF );

         cdu->keyboard_cntl ++;

     

         /* valid numbers are 0, 1, 2

          * after ENTR the count is set to -1

          * sanity check if operator presses the KYBD button

          * again after 2 the count is resets to 0

          */

     

         if (cdu->keyboard_cntl > 2) {

              cdu->keyboard_cntl = 0; }

         cdu->display_cntl = step[cdu->mode_sw][cdu->keyboard_cntl];

         /*

          * could replace switch code to:

          * blank(display_cntl);

          * cdu->cursor = 0;

     

          blank( cdu->display_cntl );

          cdu->cursor=0;

         

     

          */

        

         switch ( cdu->display_cntl ){

              case TARGET: {

                   blank( TARGET );

                   cdu->cursor = 0;

                   break; }

              case LEFT: {

                   blank( LEFT );

                   cdu->cursor = 0;

                   break; }

              case RIGHT: {

                       blank( RIGHT );

                   cdu->cursor = 0;

                   break; }

              case CENTER: {

                   blank( CENTER );

                   cdu->cursor = 0;

                   break; }

              case BOTH: {

                   blank( BOTH );

                   cdu->cursor = 0;

                   break; }}}

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • mcb1
    mcb1 over 6 years ago in reply to mcb1

    phoenixcomm

    Hey what happened white space appeared above.??

    Is it Chrome (which has trouble with some pages) or did you do some tweaking.?

     

    I have to agree that setting 'flags' and having the process alter the 'flag' makes it much easier to quickly test and determine what process to do.

     

    BTW I think your success is a Winner Winner Chicken Dinner ... I'd hate to think success is a winer   image

     

    Mark

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • phoenixcomm
    phoenixcomm over 6 years ago in reply to mcb1

    This is called Obfuscated Code and there used to be a contest every year to see who do it the best;

    But hands down Perl has to win with use Lingua::tlhInganHol::yIghun;   Klingon

    I would be a real treat to do this in Klingon (Go ahead steal my code! I double dare you!)

    Yes, I cheated. but I could have made it prettier though.

    #include

    stdio;main

    (){int a;do

    {printf("he

    llow world

    %d \n", a+

    +);}while(a

    <100) retur

    n;}

    LOL

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • 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