CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Keypad entries

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

Keypad entries
PostPosted: Sun Feb 21, 2016 1:23 pm     Reply with quote

I have my keypad entry software running which returns ASCII characters and echoes them on an LCD. I use PCM, PIC16F1938, MPLAB, ICD3 programmer.

I want to have interactive entries such as
Enter Serial number: (1 to 99, 8 bit integer)
Enter Amp-Hours: (mAH to 100 AH, some fractional such as 10.4AH)
I will have to use the * as a decimal point. The keypad has an ENTER key and UP and DOWN arrows.

The entries must be placed in strings and converted to integer and floating point numbers. I would prefer not to be forced to exact entries (e.g. S/N 7 having to be entered as 07), and have accidental letters rejected. Of course there have to be limits. I can start from scratch which would be foolish if most of the software exists already.

I have been through the CCS examples and ex_fixed.c, ex_float.c, and ex_str.c look useful. A search here in the forum only turned up programs to read the keypad such as I already have.

Does anyone have any suggestions?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 21, 2016 1:48 pm     Reply with quote

Look at this file:
Quote:
c:\program files\picc\drivers\input.c
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sun Feb 21, 2016 2:26 pm     Reply with quote

Yes, I have a printout of that and looked at it but it is uncommented, is just a page long, and does not even say what it is supposed to do. When I see code with no comments I tend to skip it which is what happened.

That said I checked the latest version and find it is now several pages instead of the one and does have a heading but still no comments in the code. It does indeed look like a useful place to start. Thank you for pointing that out PCM programmer.

I went through all the examples and even made a list of the headings for future reference. I found many examples disappointing from lack of commenting and some still have no headings and even have file names different from the example name.
temtronic



Joined: 01 Jul 2010
Posts: 9216
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Feb 21, 2016 3:40 pm     Reply with quote

If it was me, I'd grab my 30 year old TRS80 Custom Basic book that has an entire chapter on 'formatted' data entry then convert the BASIC into CCS C. Or look at what's on my 30+ year old TRS-80 III.
Nowadays though, I suppose you could 'google' 'c code formated data entry examples' or some thing similar as you are not the first one needing this type of code 'formatted data entry' does allow for 'limits', 'alpha vs numerics', 'formats', etc. and is based upon a core of low level inputs( a keypressed) returned to a 'function' that decides what needs to be done. It is a 'layered' process and there must be a zillion examples on the Web. It's one of those 'do it once, save as a personal library' projects as you'll reuse it over and over again.

I do remember doing it with a 'telephone' style keypad so you could enter letters like 'B' by pressing #2 down 3 times (2AB) within a time slice,timeout and 'B' is the returned entry. Old school stuff , efficient and small code.

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 21, 2016 3:51 pm     Reply with quote

Quote:
I found many examples disappointing from lack of commenting.

Which routines do you want to see commenting on ?
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sun Feb 21, 2016 4:35 pm     Reply with quote

First of all I'm not using RS232 or higher level functions which is probably half my problem..
As an example consider the following code:
Code:
 // get battery serial number
  sprintf(buff, "Battery S/N ?");       // place text string in buffer
  text_position(0,1);                      // start, second line
  send_str(buff);                           // display text array
  for (i=2; i>0; i--)             // get S/N in reverse order
   {
    while (!key)                   // wait for ISR to trigger
     NOP;                            // do nothing
    bat_SN[i] = key;            // save serial number
   }

The serial number is going to be entered backwards so I either have to enter as shown with a problem of the null for the string, or I have to reverse the array after entry.
The next problem is I cannot find an equivalent of assembly NOP unless the K&R dummy() function is what is required.
I could forget the ISR and make the keypad entry a function then use it within a C function like getc. I forget how but I think I did something similar once before.
What happens if I enter 10.3 ampere hours in one situation, then 0.1200 AH for the next. Am I just making life difficult expecting variable format floating point numbers and should all entries be xx.xx so the examples must be entered as 10.30 and 00.12 ?
This is a spinoff project from my battery monitor in my ROV. That was easier because there was no ASCII entries from a keypad to deal with.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 21, 2016 5:47 pm     Reply with quote

Quote:
The serial number is going to be entered backwards

Why does it have to be entered backwards ?


Quote:
The next problem is I cannot find an equivalent of assembly NOP

It's this:
Code:
delay_cycles(1);

But why do you need it ? You can just put a semi-colon at the end of
the while statement, and it will loop while key == 0. Example:
Code:
while (!key);


Quote:

What happens if I enter 10.3 ampere hours in one situation, then 0.1200
AH for the next.

Get those numbers as strings, and atof() will convert them to floats.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sun Feb 21, 2016 6:13 pm     Reply with quote

Thanks PCM.
When you enter 23 on a keypad the 2 goes into the array first, then the 3 so if you read it out in sequence it comes out 32. It has to be switched somewhere.
It's getting the characters into strings that is the problem. Once converted to numbers the problem is solved.

Correction! I have been thinking shift registers. Of course the characters are stored first in first out. Embarassed
temtronic



Joined: 01 Jul 2010
Posts: 9216
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Feb 21, 2016 7:52 pm     Reply with quote

for (i=2; i>0; i--) // get S/N in reverse order

Not to sure WHY you're counting backwards......

for(i=0;i>2;i++) // should work for you...

Jay
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sun Feb 21, 2016 9:49 pm     Reply with quote

temtronic see my correction above.
I now have my string entry working:
Code:
    char buff[buff_size];
      char bat_SN[8]="ABCDEF";              // batery serial number
// get battery serial number
  sprintf(buff, "Battery S/N ?");       // place text string in buffer
  text_position(0,1);                   // start, second line, LCD function
  send_str(buff);                       // display text array, LCD function
  for (i=0; i<2; i++)                   // get characters
   {
    while (!key);                           // wait for key press
    bat_SN[i] = key;                     // store the character
    key=0;                                   // clear the flag for ISR
   enable_interrupts(INT_RB);  // reset the interrupts that
   enable_interrupts(global);    // were cleared in the ISR
   }
// display S/N
  sprintf(buff, "Battery S/N = %s", bat_SN);       // place text string in buffer
  text_position(0,2);                   // start, second line
  send_str(buff);                       // display text array

The problem now is that I want to enter more parameters into the string but only access certain ones. I guess I have to copy them out to another array. I cannot selectively select with sprint() I don't think. Say to copy array(5 to 7) to the buffer. For example I can't do the following much as I would like to
Code:
for (i=5; i<8; i++)
  sprintf(buff, "Battery S/N = %c", bat_SN[i]);       // place text string in buffer

Most of the code is in my previous posting "Interrupt does not work with different PIC" that is resolved. I hope these relevant parts are enough to get the idea across.
Ttelmah



Joined: 11 Mar 2010
Posts: 19480

View user's profile Send private message

PostPosted: Mon Feb 22, 2016 2:36 pm     Reply with quote

If you have an array. Say text[10]. Then text[3] or *(text+3), is the single _character_ at the fourth location in the array. You can print this just as any other character.

What you post will do this, but because of the way you have it written, will output the whole line with just one character each time, rather than the multiple characters. You need to separate the message output, then just append the characters.

Code:

   sprintf(buff,"Battery S/N = ");
   for (i=5; i<8; i++)
      sprintf(buff+i+9, "%c", bat_SN[i]);       // place characters in buffer
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Mon Feb 22, 2016 8:31 pm     Reply with quote

Thanks for the great tips. I will try them out.
These are my thoughts on what I want to accomplish.

I want to store battery data in EEPROM (non-volatile memory) by battery serial number (s/n).
The first location will contain the last s/n stored and will be set to 0 at initial programming. Battery data will be stored in blocks accessed by the serial number of the battery and an offset. [(s/n – 1) * offset + 1] so, for example, with an offset of 10 the s/n 1 data starts at 1, s/n 2 starts at 11, etc. The s/n does not need to be stored.

A block of data may look like this:
Type of battery: 1=Lead Acid, 2=Gel, 3= NiCad, 4=NiMH, 5=LiPO, 6=LiFePO4 (integer)
Number of cells. This is used to get the battery voltage and the discharge voltage point. (integer)
Rated A-H. This is used to set the standard discharge current for testing. (float)
The measured A-H at the standard discharge current. (float)
The optional measured A-H for a specific current. (float)
The specific current for the optional A-H measurement. (float)

The program will ask for the s/n and if new will ask for Type, number of cells, and rated A-H. The rest will be calculated as requested. If the s/n is not new then the data is retrieved and displayed waiting for an instruction.

Display output will be to a working 128x64 serially driven graphics LCD described in one of my posts in this forum. It makes graphics a snap.
Input is the question now. I can input to an array as just described above but, and correct me if I’m wrong...
As has been pointed out to me there are better ways. There is a way to place a function to replace normal I/O. For example in another application I used
Code:
printf (lcd_putc,"\fVolts = %f\n", volts);

where lcd_putc was a function in an include file.
It seems fgetc() will input a single character and fgets() will input a stream while scanf() does not seem suitable for this application. There may be others.
If I write a keypad input function I can place it in fgetc() or fgets() as the source string something like this:
Code:
char get_keypad (void);         // function prototype
char buffer [20];         // buffer big enough for all entries
int max=2;            // # of char expected
fgets(buffer, max, get_keypad);      // get the string of ASCII characters into the buffer
This would enter the characters into the buffer. Next I need to convert the characters to integer or floating point. atoi() will convert a string of ASCII entries into integer. atof() will convert a string of ASCII entries into floating point. Now I can store the data into EEPROM.

Question: Is there a way to use the ISR keypad entry with fgetc() or fgets() instead of re-writing it as a function ? Interrupt has the advantage of being able to abort the current operation.
Question: input.c looks interesting. How do I use it? I could copy the functions I need and modify them. Is it intended to be used as an include file? I know the general meaning of ifndef and ifdef but I have no idea how I would define anything for this program. I need just one example and where I would place it.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group