Go Down

Topic: function parameter types (Read 104 times) previous topic - next topic


I wrote this sketch years ago for a solar panel tester, it works fine as is, question is, can function "lcdNum" be written to accept numbers of any type, whether byte, int, long or float?
I'm nearly 70 and probably won't live long enough to learn the finer points of C/C++, besides I only write code for MCU projects and don't plan to write any databases or word processors. ;)
Code: [Select]

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);

int eVal, iVal, res, ofst;
byte curCol, curLine, bkLite = 6;
float volts, amps, watts;
const float vdComp = 89.6; // compensation for voltage divider
const float oaComp = 1808.0; // compensation for op amp gain
long ohms;

void setup()
  lcd.init();                      // initialize the lcd
  analogWrite(bkLite,96);          // backlight brightness
  eVal = analogRead(0);
  iVal = analogRead(1);

void loop()
    Serial.print("ch 0...");
    eVal = getADC(0, eVal);      // read voltage
    volts = eVal / vdComp;
    Serial.print("ch 1...");
    iVal = getADC(1, iVal);
    amps = iVal / oaComp;
    watts = volts * amps;
    ohms = (amps <= 0) ? -1 : volts / amps;
    if(ohms > 9999999) ohms = -1;


int getADC(byte ch, int adcVal)
  unsigned int accu = 0;
  for(byte i = 0;i < 16;i++)
    accu += analogRead(ch);
  Serial.print(accu, HEX); Serial.print("  ");
  if((accu & 0x000F) > 2 && (accu & 0x000F) < 0x0D)
    adcVal = accu / 16;
  adcVal = (accu > 16) ? adcVal : 0; 
  Serial.print(adcVal, HEX); Serial.print("  ");
  Serial.print(adcVal); Serial.print("    ");
  Serial.print(watts, 3); Serial.print("  ");
  Serial.print(volts); Serial.print("  ");
  Serial.println(amps, 3); Serial.print("\n\n");
  return adcVal;

// Function lcdNum
// Call with number to display (FLOAT), decimal point column,
// line number (0 to 3),number of columns before DP (start with 4),
// number of columns after decimal point (try 3)

void lcdNum (float num, byte dpcol, byte line, byte bdp, byte adp)
  long  tmp;
  byte offset = 1;
  tmp = num;
  while(abs(tmp) >= 10){
    tmp /= 10;
    offset ++;
  if(num < 0) offset ++; 
  lcd.setCursor(dpcol - bdp, line);
  for(byte i = 0;i < bdp + adp + 1;i ++)
    lcd.print(" ");   
  lcd.setCursor(dpcol - offset, line);
  lcd.print(num, adp);

BTW, lcd is QC2004A 20 X 4 and  I2C backpack is LCD2004, both from SainSmart.


Yes, it's as simple as writing the alternate functions, for example:

Code: [Select]
void lcdNum (byte num, byte dpcol, byte line, byte bdp, byte adp) {//...}

Yay, C++ !
... with a transistor and a large sum of money to spend ...


Maybe I should have said called with any number type.


You have to write a version of lcdnum for each type of argument you want to use.
byte/int/long can all be handled together, since the function call will "promote" everything to long, so you usually just need versions for long and float.  (actually, byte/int/long would get promoted to float if you only implemented float, so you'd really only need multiple versions if you want to format integers differently than floats, or care a lot about efficiency.


Thanks for reply though thats what I was thinking, I thought there might be a way using unions or pointers, etc. but thats too far over my ol' head to even start on.


There are also function templates which let you write a function once and have the compiler write different versions for you for each type that gets used.
Ad hoc, ad loc, and quid pro quo.  So little time - so much to know!  ~Jeremy Hillary Boob Ph.D

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131