Pages: [1] 2 3 ... 10   Go Down
Author Topic: Structure of code. Need help.  (Read 6674 times)
0 Members and 1 Guest are viewing this topic.
Oz
Offline Offline
God Member
*****
Karma: 4
Posts: 703
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have asked, and been told/pointed to C sites, but I am not understanding what is written on these sites.

Partly because I think the layout of the code examples.

The lists seem to have the functions BEFORE the actual "program".

Indulge me please:

I don't know if this is helping or not but here are some questions with what I see as the problem/s:

I won't put it in "CODE" format, because it isn't really real code.

The main loop looks like:

VOID ROUTINE_I_WANT_TO_CALL()

To me, that means that the routine is called with no paramaters (why does this show as bad spelling?) and returns nothing.   Though obviously that would be somewhat silly.

ROUTINE_I_WANT_TO_CALL
{
    Things here which do what ever
}

Ok, the { starts the FUNCTION and } ends it.

If I want to send something to the routine - when it doesn't initially accept things, what do I do?
I get I do:
VOID ROUTINE_I_WANT_TO_CALL(what ever it is I want to send)

Now, another question:
I know it has been "explained" but I still can't get my head around it.
What is the difference between:
j = THE_ROUTINE()
and
j THE_ROUTINE()

I don't know if having anything between the ()'s in either would change anything.

Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 289
Posts: 25697
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
paramaters (why does this show as bad spelling?) a
Hmm, let me think...

It really would be better if you kept it to actual code examples; your pseudocode is a long way from C syntax, it is hard to understand.

For instance,  it is hard to decide what you mean by
Quote
j THE_ROUTINE()
« Last Edit: June 09, 2012, 04:38:04 am by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

When you create a function you specify both the type of data you want to work with and the name of the variables to store that data.

For instance:

Code:
void myFunction()
{
  ...
}

creates a function that takes no data and receives no data, and:

Code:
int myFunction(float myVar)
{
   return myVar*1000;
}

creates a function which takes a single value that is a floating point number, and returns a value which is an integer number.  The value you send to the function is stored in the variable "myVar".  (In this case the function returns the number you sent multiplied by 1000).

When calling the function you have the option of assigning the results of the function (the value "return"ed) into a variable.  For example:

Code:
int result;

result = myVar(13.442);

Using the second function we defined above, "result" would now contain 13442.

Note that the data type of "result" (int) matches the return type of the function (int).

In C everything happens inside functions (well, not including global variable declarations).  The program always starts by running the "main()" function.  The Arduino system writes this function for you.  That function first calls the "setup()" function, and then repeatedly calls the "loop()" function.

The order the functions are in within your program is of no importance.  Normally it does matter, because a function has to be defined before it can be used, so traditionally all functions go before the "main()" function, but the Arduino compilation system fudges it all around so it doesn't matter what order you write the functions in.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Oz
Offline Offline
God Member
*****
Karma: 4
Posts: 703
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

AWOL,

This has been said before.

I am learning and now can explain why I can't/don't.

The problem is that I don't always know what is relevant and what isn't.  Yes that contributes to the problem, but from my point of view, it is silly/confusing putting things in which I don't understand.

AND!

People reply with stuff which is WAY beyond me understanding.

I luckily worked out some problems by sheer bashing my head against the wall.

Sometimes there are parts of the code/program which have things I want.  But I don't know how to get those "names" to another part of the code.

That was PARTLY covered by my first couple of examples.

But it is so confusing for me.

I guess there is middle ground but the terms used are too "in the know" for me and how they are formatted.

Logged

Oz
Offline Offline
God Member
*****
Karma: 4
Posts: 703
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is a bit of code on which I am stuck:

Code:
class alarm_clock
{
public:
  alarm_clock(boolean noo);
  byte run(); // Returns which alarm is triggered, 0-Max_alarms, 255 means no alarm is triggered.
  byte set_alarm(byte alarm_num, byte hr, byte mnt, byte dow); // Returns 255 if parameters are invalid. Returns 0 if valid.
  void turn_on(byte alarm_num);
  void turn_off(byte alarm_num);
  void alarm();
  boolean within(byte a, byte dow);
 
  typedef struct {
  byte hr;
  byte mnt;
  byte dow;
  boolean on_off; // This variable is not used. Instead dow is used to turn the alarm off or on.
  }
  entry;

  entry alarms[Max_alarms];
  boolean alarm_is_on; // Alarm is on. alarm() will be called if this is true.
  byte snooze;
};
#endif


byte run(); // Returns which alarm is triggered, 0-Max_alarms, 255 means no alarm is triggered.


Excuse the "language" but: What the....?

I would like to get a variable with which alarm number is active available in the main program.
I want to put a symbol on the screen when an alarm is set as well as another when an alarm is active.
A number which is unique to the alarm - which the program gives - would be handy.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 289
Posts: 25697
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm trying to help, but it's a bit like being shown a bolt and saying "it doesn't work".
Maybe the nut is the wrong diameter, or the thread pitch is wrong, or it's a left handed thread, but without seeing the whole picture, it is near impossible to say what the problem is.

Don't get hung up on the language, but don't abstract it further to make it more incomprehensible.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What you have there is a class definition.  That in itself doesn't do much - you need the class code to go with it.

With classes you first have to create an object from the class.  The creator of the class may have done this already for you, or you may already have done that.  Classes are a complex subject.

You create a class object kind of like making any variable type:

Code:
alarm_clock myAlarm;

Then you can access any of the functions within that class by referencing them as methods of the object:

Code:
byte triggeredAlarm;

triggeredAlarm = myAlarm.run();

triggeredAlarm will then contain the results of the run() function from inside the myAlarm alarm_clock object.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 64
Posts: 2101
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The main loop looks like:

VOID ROUTINE_I_WANT_TO_CALL()

To me, that means that the routine is called with no paramaters (why does this show as bad spelling?) and returns nothing.

The void does not belong in a function call. The function is declared to either return or not return.
You can however choose to ignore the returned value if it does return one.

So it would just be

Code:
void loop(){
  ROUTINE_I_WANT_TO_CALL();
}

And ROUTINE_I_WANT_TO_CALL will have to be defined somewhere:

Code:
void ROUTINE_I_WANT_TO_CALL( void ){
  //some lines of code.
}

And maybe for the post you just added: you could use a global variable to store the alarm number.
Posting all your code will prevent some assumptionizing.


Logged


Oz
Offline Offline
God Member
*****
Karma: 4
Posts: 703
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Would this be any better?

Code:
alarm_clock::alarm_clock(boolean noo) // This parameter is need otherwise the compiler won't work with a constructor without parameters.
{
  alarm_is_on=false;
  snooze=10;
}

/* 
Need to look at this part.  Apparantly run() returns WHICH alarm is active.
So I need to work out where the returned value is stored.
*/
byte alarm_clock::run()
{

  //  Here is my effort to detect WHICH alarm is active.
  //lcd.setCursor(10,0);
  //lcd.print ( What do I put here to get the returned value from run()?  );
  // this is the bell signal indicating an alarm is active.

  int rtc[7];
  render_RTC(clock_style);
  RTC.get(rtc,true);
  for (int i=0;i<4;i++)
  {
    if ((alarms[i].hr==rtc[2])&&(alarms[i].mnt==rtc[1])&&(rtc[0]==0)&&within(i,rtc[3]))
    {
      alarm_is_on=true;
    }
  }
  if (alarm_is_on) alarm();
}

byte alarm_clock::set_alarm(byte alarm_num, byte hr, byte mnt, byte dow)
{
  if (alarm_num>=Max_alarms) return 255;
  if (hr>23) return 255;
  if (mnt>59) return 255;
  alarms[alarm_num].hr=hr;
  alarms[alarm_num].mnt=mnt;
  alarms[alarm_num].dow=dow;
  return 0;
}

void alarm_clock::alarm()
{
  int act_alarm_num=0;   // this is for me to adjust the horizontal position of the indicator for which alarm is active.

  // I am going to have to alter the position and the symbol shown here at 0,0 later on
  //  Also, the first digit in both these needs to be altered to reflect which alarm it is.
  lcd.setCursor(act_alarm_num*4,0);
  lcd.print (char(0));  // this is the bell signal indicating an alarm is active.

  lcd.setCursor(act_alarm_num*4+2,0);
  lcd.print (alarm_run_time);  //  This shows how long the alarm has left to run - NOT WORKING YET!
 
  //char msg[4];
  //sprintf(msg," %02d",alarm_run_time);  // don't know why this doesn't work.
  //lcd.print(msg);
 
  //byte alarm_clock::set_alarm(byte alarm_num, byte hr, byte mnt, byte dow)
  //lcd.setCursor(0,1);
  //lcd.print(alarm_num);

  int temp1;
  for (int i=0;i<4;i++)
  {
    digitalWrite(light,HIGH);
    digitalWrite(alarm0,LOW);
    temp1=wait_on_escape(75);
    if ((temp1>0))
    {
      digitalWrite(light,LOW);
      digitalWrite(alarm0,HIGH);
      lcd.setCursor(0,0);
      lcd.print("    ");
      alarm_is_on=false; // Turn off alarm
      return;
    }
  }
}
Logged

Oz
Offline Offline
God Member
*****
Karma: 4
Posts: 703
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The alarm code is HUGE!

(It is beyond the size limit for posting in a thread)

I don't know how to do it any other way.

Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
/* 
Need to look at this part.  Apparantly run() returns WHICH alarm is active.
So I need to work out where the returned value is stored.
*/
byte alarm_clock::run()
{

  //  Here is my effort to detect WHICH alarm is active.
  //lcd.setCursor(10,0);
  //lcd.print ( What do I put here to get the returned value from run()?  );
  // this is the bell signal indicating an alarm is active.

  int rtc[7];
  render_RTC(clock_style);
  RTC.get(rtc,true);
  for (int i=0;i<4;i++)
  {
    if ((alarms[i].hr==rtc[2])&&(alarms[i].mnt==rtc[1])&&(rtc[0]==0)&&within(i,rtc[3]))
    {
      alarm_is_on=true;
    }
  }
  if (alarm_is_on) alarm();
}

This function does not return anything.  It should.

I guess that alarms[] is an array of alarm settings - and you have 4 of them (0 to 3).

You will want to remember which alarm iteration number you found was on in another variable, then return that variable.  Something like:

Code:
/* 
Need to look at this part.  Apparantly run() returns WHICH alarm is active.
So I need to work out where the returned value is stored.
*/
byte alarm_clock::run()
{

  //  Here is my effort to detect WHICH alarm is active.
  //lcd.setCursor(10,0);
  //lcd.print ( What do I put here to get the returned value from run()?  );
  // this is the bell signal indicating an alarm is active.

  byte active_alarm = 0;   /* */
  int rtc[7];
  render_RTC(clock_style);
  RTC.get(rtc,true);
  for (int i=0;i<4;i++)
  {
    if ((alarms[i].hr==rtc[2])&&(alarms[i].mnt==rtc[1])&&(rtc[0]==0)&&within(i,rtc[3]))
    {
      alarm_is_on=true;
      active_alarm = i+1;  /* */
    }
  }
  if (alarm_is_on) alarm();

  return active_alarm;  /* */
}

That will return 0 for no alarm active, or 1 to 4 for an active alarm.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Oz
Offline Offline
God Member
*****
Karma: 4
Posts: 703
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, but WHERE does it return the value?

And what is all that stuff in the first line?


(sorry just noticed that all I posted didn't go in!)

This is up the top:

Code:
alarm_clock::alarm_clock(boolean noo) // This parameter is need otherwise the compiler won't work with a constructor without parameters.
{
  alarm_is_on=false;
  snooze=10;
}

/* 
Need to look at this part.  Apparantly run() returns WHICH alarm is active.
So I need to work out where the returned value is stored.
*/
byte alarm_clock::run()
{


This is a good example of me not knowing what I am posting and though you have told me an answer, I can't see where you get it - well I kind of can - but how I see it and what I see, is confusing.

So what is all this:
alarm_clock::alarm_clock(boolean noo) // This parameter is need otherwise the compiler won't work with a constructor without parameters.


Huh?

Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That is called the "Class constructor".

This is code which is called when you create the class object with

Code:
alarm_clock myAlarm;

It is used to initialize default values and set up the system ready for the alarm clock to operate.

The run() function returns the value to wherever you assign it when calling the function.  If you never call the function then you never get the value.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Oz
Offline Offline
God Member
*****
Karma: 4
Posts: 703
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So how do I get the number of the alarm?

The code says this run() returns the alarm's number.
(refer first bit of code)

So "somewhere" there is the code which will yield the active alarm number.

But I still can't find it.

Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Your run() function as it stands doesn't return jack.

The version I modified does return the alarm number that triggered, or 0 for no alarm.  The lines with /* */ after them are my additions.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Pages: [1] 2 3 ... 10   Go Up
Jump to: