Author Topic: Combine three variables into one  (Read 2794 times)

0 Members and 1 Guest are viewing this topic.

Offline AcHmed99Topic starter

  • Contributor
  • Posts: 35
  • Country: 00
Combine three variables into one
« on: June 22, 2016, 11:18:59 am »
I'm using a PIC16F1717 for reading a pushbutton menu and writing results to the display for a variable output SMPS. The SMPS output is controlled by the 8b DAC on the PIC. I have 4 pushbuttons one for select, one for UP, another for Down and one to Shift the cursor to the value the user wants to adjust. An example selection may be 4.82V. I store 4 in ones,8 in hundreds and 2 in tens. Each ones = 50 steps on the DAC, each hundreds=5 steps on the DAC,the tens are incrementing/decrementing 20mV increments which is the resolution one step.

For the 4.82V example I need a way to convert that to four hundred and eighty two (482) then divide that result by two which gives 241 DAC steps, check that its within range less then 256 but greater then 40 steps (output range 5.10V-0.8V). Is there a way to do that without using addtion? Or is there a way to track the DAC directly from the user input?

Here is a snip of the function used to track user input on a down pushbutton push.The UP button function is identical only values are incremented.

Code: [Select]
/***************************DWN_Button******************************************
Function for decoding down push button push. If we are this far a valid push is
assumed and appropriate action (decrement) value at the saved cursor postion
ones,tens or hundreds via switch case.
*******************************************************************************/
void DWN_Button(){

     switch (curs_pos){
//We are at postion 11 or tenths.
            case 11:
                  if(tens == 0){          //last postion was zero so wrap
                          tens = 8;       //around
                          i = (tens)+ 48; //Change value to ASCII for display
                          WriteVal();     //go write value
                          return;
                          }
                  else{
                          --tens;         //20mV resoulotion so dec twice
                          --tens;
                          i = (tens)+ 48; //Change value to ASCII for display
                          WriteVal();     //go write value
                          return;
                          }
            break;
//We are at hundreths cursor postion 10. Same procedure from tens is followed
            case 10:
                  if(hundreds == 0){
                          hundreds = 9;
                          i = (hundreds)+ 48;
                          WriteVal();
                          return;
                          }
                   else{  --hundreds;
                          i = (hundreds)+ 48;
                          WriteVal();
                          return;
                          }
            break;
//We are at ones cursor postion 8. Same procedure from tens is followed
            case 8:
                  if(ones == 0){
                          ones = 5;
                          i = (ones)+ 48;
                          WriteVal();
                          return;
                          }
                   else{  --ones;
                          i = (ones)+ 48;
                          WriteVal();
                          return;
                          }
            break;
//We should never get this far but its here just in case.Error invalid cursor
//postion DON'T FORGET TO WRITE ERROR HANDLER.
            default:
                    Lcd_Cmd(_LCD_CLEAR);    // Clear display
                    Lcd_Out(1,2,message1);  //error message invalid input
            break;
   }
}

//***********************End DWN_Button***************************************
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Combine three variables into one
« Reply #1 on: June 22, 2016, 11:35:13 am »
"Is there a way to do that without using addtion? "

You certainly can make it through subtractions, divisiionss, log transformation or something even more complex.

But why is addition so offensive here that you have to avoid it?
================================
https://dannyelectronics.wordpress.com/
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: Combine three variables into one
« Reply #2 on: June 22, 2016, 12:18:40 pm »
Quote
Or is there a way to track the DAC directly from the user input?
a closed loop where you read the input voltage and change the dac output when the input doesn't match the set point (user input) with all the fun involved

but to answer the first question, since you don't have a dsp on board it will be much much.. much much faster to keep track of the three digits and reconstruct the binary value than the other way around. you can hand optimize the functions as you will have to do
(X + 10 * Y + 100 * Z ) / 2
X, Y go from 0 to 9 -> 4 bit -> the 8x8 bit multiplication routine will always have 4 times when you don't need to do nothing, second bit is always zero.
Z goes from 0 to 5 -> 3 bit -> 5 cycles of wasted time
at the end you'll have a number from 0 to 511 (0 to 255 + carry), so RRC and you have your 0-255 number.

this of course has to be done only once, if you change a digit at a time you just have to adjust the "digit" by adding/subtracting 1,5,10,50,100,whatever
« Last Edit: June 22, 2016, 12:30:19 pm by JPortici »
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11622
  • Country: my
  • reassessing directives...
Re: Combine three variables into one
« Reply #3 on: June 22, 2016, 12:39:19 pm »
why you:
1) need to process 47K down button a second?
2) care to ask to optimize 99.2% free resources?
3) want to find simpler than ADD instruction?
4) dont combine UP and DOWN button in one single switch branch to further optimize your 99.2% free resources?
5) put tenth decimal in hundreds and hundreth in tens?
this is way too much confusing...
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 
The following users thanked this post: Delta

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Combine three variables into one
« Reply #4 on: June 22, 2016, 01:09:00 pm »
You are essentially asking if there are more efficient ways without using the most efficient way. I think the answer there is obvious.

As to the button processing, yeah, it does look quite inefficient.
================================
https://dannyelectronics.wordpress.com/
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: Combine three variables into one
« Reply #5 on: June 22, 2016, 02:29:04 pm »
There is a different way to code the switch processing when you notice how much code is invariant within the if..else.. statement:
Code: [Select]
if(ones == 0){
    ones = 5;
    i = (ones)+ 48;
    WriteVal();
    return;
}
else{
    --ones;
    i = (ones)+ 48;
    WriteVal();
    return;
}

This could be written as:

Code: [Select]
if(ones == 0){
    ones = 5;
}
else{ 
    --ones;
}
i = (ones)+ 48;
WriteVal();
return;

Maybe this form makes it more clear what is being done as a result of the switch press.
« Last Edit: June 22, 2016, 02:32:28 pm by rstofer »
 

Offline Buriedcode

  • Super Contributor
  • ***
  • Posts: 1611
  • Country: gb
Re: Combine three variables into one
« Reply #6 on: June 22, 2016, 02:37:51 pm »
Unless these switch statements are being run inside a control loop, I don't see what the big deal is. The idea of manually adding/subtracting values from variables (like adding 50 to the DAC output if the 'ones' is pushed) is already pretty efficient if that device doesn't have hardware multiply. And if you're just incrementing/decrementing the DAC value based on user inputs, there is no control loop anyway.  I assume you're not updating the DAC with the new value until the user presses the enter button?  That allows the user to change all the digits and update all at once rather than clumsily jumping up and down the scale as one hits buttons.

The up and down buttons essentially do the same thing for each digit, the only variables there are the upper limit (roll over, 9, or 5) and what value to add/subtract from the DAC.  As the 'ones', 'hundreds' and 'tens' are global variables theres no need to pass these to a function, and keeping track of what digit is selected is just on char.  Perhaps a smaller function that returns the DAC step value for inputs 0-2 (each digit) and the upper limit value (9, or 5) that's called for up or down.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: Combine three variables into one
« Reply #7 on: June 22, 2016, 03:03:17 pm »
The conditional operator is a matter of style and many won't use it but...

Code: [Select]
if(ones == 0){
    ones = 5;
}
else{ 
    --ones;
}

could be coded as:

Code: [Select]
ones = (ones == 0) ? 5 : ones - 1;

Using such a statement might make your code shorter and easier to read.  But it's a matter of style and a lot of folks would prefer the if {} else {} structure.

 

Offline Buriedcode

  • Super Contributor
  • ***
  • Posts: 1611
  • Country: gb
Re: Combine three variables into one
« Reply #8 on: June 22, 2016, 03:17:19 pm »
also whilst the compiler probably produce less instructions, you can always decrement and check for underflow,

Code: [Select]
if (--ones == 0xFF) ones = 5;
 

Offline Buriedcode

  • Super Contributor
  • ***
  • Posts: 1611
  • Country: gb
Re: Combine three variables into one
« Reply #9 on: June 22, 2016, 08:46:27 pm »
I know there have been many projects using a micro as the controller, but for LED's the current limit loop should be fast to prevent voltage overshoot.  I'm probably in the minority but for a 'testing' power supply that may be used for almost anything (as in, not hardwired to power a particular circuit) I wouldn't use a micro for it.

But with that said, if your micro is just handling the user input, the display and outputting a value to the DAC, it'll have more than enough room, and execution time for many extra features should you wish to add them.  And it's enough for *some* maths (16x-16 bit multiplication, or division) that will of course be done just in software but it'll still take less than a millisecond at 4MHz.

I can see why you were a bit unhappy with the various switch-case statements.  They can start to look clumbsy and out of hand, and sometimes is just nicer to merge things into what appears to be a more efficient loop.  But depends on the restrictions you impose, with little int he way of memory/execution time restrictions, there is still 'readability'.  I often go back to old projects I've done for PIC's and AVR's and have to spend far too long re-familiarizing myself with the algorithm - not because its bad, but because it was highly optimised and not obvious what its actually doing.  Sure its nice to seem clever to yourself, but it becomes a real pain if you, or someone else has to modify it.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: Combine three variables into one
« Reply #10 on: June 22, 2016, 08:49:43 pm »
Eventually, you will want the entire keyboard operation to be interrupt driven.  You will want to get it out of the control loop and over to one side.
Some kind of tiny RTOS is probably the way to go.  The keyboard interrupts do as little as possible but once <ENTER> is detected, a message is posted to the control loop to change the settings.  Since there is every possibility that there will be incorrect key presses, you need a way to deal with them.  You have already updated the display but not the output (before <ENTER>) so you need to roll the display back after some timeout or cancel key.

The UI is often the hardest part.
 

Offline altaic

  • Supporter
  • ****
  • Posts: 45
Re: Combine three variables into one
« Reply #11 on: June 22, 2016, 09:21:23 pm »
Eventually, you will want the entire keyboard operation to be interrupt driven.

This. Polling and UI should never go together.
 

Offline Buriedcode

  • Super Contributor
  • ***
  • Posts: 1611
  • Country: gb
Re: Combine three variables into one
« Reply #12 on: June 23, 2016, 12:15:53 am »
These uc's have all the analog and digital perphials on board to make your own SMPS peak current mode controller. Look at the block diagram of the internals of the old UC384X, that is essentially what I've built using the Analog perphials and internal CLC's. I set-up all the analog and the CLC's and just let it run no intervention needed.

Wonderful isn't it?  As always I didn't really look into those devices when they came out and only last year appreciated the versatility.  Sure the opamps have pretty bad offset, and the internal voltage references aren't great but there are *many* projects that don't require those.  I've sadly become a bit of a fanboy of the 16F17xx series :/ often with just one on a bit of stripboard and a few passives doing wonderful things 
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Combine three variables into one
« Reply #13 on: June 23, 2016, 11:13:06 am »
Rather than calculating the value from three "variables", you could simply add to or subtract from it 100/10/1 based on the keys pressed, with boundary checks obviously.
================================
https://dannyelectronics.wordpress.com/
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: Combine three variables into one
« Reply #14 on: June 25, 2016, 04:05:51 am »
Premature optimization is always a mistake.  Among other things, the wrong things get optimized.

Quote
The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming

Donald Knuth
 
The following users thanked this post: altaic


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf