Mindstormsforum Dateiupload | Links | Lexikon | NXT Shop | RobotC.de | Wettbewerbe |    Seitenreport - Die SEO und Website Analyse

bild
bild
Unbeantwortete Themen | Aktive Themen Aktuelle Zeit: 30. Okt 2014 15:26


Auf das Thema antworten  [ 2 Beiträge ] 
NXC: MS NumPad als alpha-numerische Tastatur (C-Konsole) 
Autor Nachricht
Administrator
Administrator
Benutzeravatar

Registriert: 11. Jan 2006 21:01
Beiträge: 4347
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze
Beitrag NXC: MS NumPad als alpha-numerische Tastatur (C-Konsole)
für alle, die ein Mindsensors NumPad besitzen (LINK):
jetzt als alpha-numerische Tastatur verwendbar!
Bild
0-9 A-Z + - . : (in Verbindung mit Sondertasten [*] und [#] sowie [ *# ] gleichzeitig):

(statt des C-Befehls printf könnte man zur Bildschirmausgabe auch NXC-TextOut verwenden - die Rechnerei mit der Cursor-Positionierung und Zeilenumbruch macht aber "mein" printf automatisch!) ;)

Code:
/************************************************************************/
//
// Program Name: NP-io.nxc
//
// ver. 2.04
// (c) HaWe 2012-Nov
//
// featuring C-like functions from <stdio.h>, <conio.h> :
//=======================================================
// int    getch()               // reads key from numpad, no echo on screen
// string gets(string)          // reads string from numpad + echo on screen
// char /*bool*/ kbdhit()       // tests if key hit on numpad, no return, no echo
// char   cin /*no pipelining*/ // reads single key from numpad, no echo on screen
// printf (fmtstring, variant)  // displays formatted char, string, int, float

/************************************************************************/

// default: attach Numeric Pad to PORT 1.
//
// key presses: digit + optionally * or # or #*
// long press *  => Backspace
// long press #  => Space (Blank)
// long press *# => Enter (end of input)
//
// share and enjoy !
//
//




#include "NP-lib.h"

//*********************************************
int _cur_x_=0, _cur_y_=56;      // cursor home for NXC  = upper left = (0,56)
int _tab_width_=24;             // tab width by default = 24 = 4* 6-point letter

unsigned long _TEXTSTYLE_ = DRAW_OPT_NORMAL;   // text style by default

#define scrclr() {  ClearScreen();  _cur_x_=0; _cur_y_=56; }

#define gotoxy( x, y )    { _cur_x_=x; _cur_y_=y; }   // move cursor to position
#define curxy( x, y )     { _cur_x_=x; _cur_y_=y; }   // move cursor to (alias)
#define curx  ( x )       { _cur_x_=x; }              // move cursor to x-pos
#define cury  ( y )       { _cur_y_=y; }              // move cursor to y-pos
#define curhome           { _cur_x_=0; _cur_y_=56; }  // move cursor home
#define settabwidth( t )  { _tab_width_ = t; }        // redefine tab width
#define settextstyle( t ) { _TEXTSTYLE_ = t; }        // redefine text style

//*********************************************

inline string strsplit(string &src, string mark) {
  string _sret="";
  int p=-1, l;
  p=Pos(mark, src);
  if (p>=0) {
    l=strlen(mark);
    _sret= SubStr(src, 0, p);
    src=SubStr(src, p+l, strlen(src)-p);
  }
  return _sret;
}

//*********************************************

string strexch(string src, string ex, string ch) {
  string _sst;
  _sst=strsplit(src,ex);
  return (StrCat(_sst,ch,src));
}

//*********************************************

void backspace() {
  TextOut(_cur_x_, _cur_y_, " ");
  if (_cur_x_ >=6) _cur_x_-=6;
  else if ((_cur_x_ ==0)&&(_cur_y_ <56)) {_cur_x_=90; _cur_y_ +=8; }
  TextOut(_cur_x_, _cur_y_, " ");
}

// printfxy()
// featuring "\i" for writing inverted
//******************************************************************************
#define printfxy( _x_, _y_, _f_, _v_) { \
  _cur_y_=_y_;   string  _s2, _sv;      \
  _s2=_f_;                              \
  if (Pos("\i",_s2)>=0) {               \
    _TEXTSTYLE_= DRAW_OPT_INVERT;       \
    _s2=strexch(_s2,"\i","");           \
  }                                     \
  int len=0;                            \
  if (Pos("%",_s2)==-1)  { _sv=_s2; }   \
  else { _sv = FormatVal(_s2, _v_);  }  \
  TextOut(_x_, _y_, _sv, _TEXTSTYLE_);  \
  len=strlen(_sv);                      \
  _cur_x_=_x_+6*(len);                  \
  _TEXTSTYLE_= DRAW_OPT_NORMAL;         \
}


// printfEx redefined as printf()
// featuring \n, \t, and "\i" for writing inverted
//******************************************************************************
#define printf(_fmt, _val) {             \
  int _x=_cur_x_; int _y=_cur_y_;        \
  string _sf, _s;                        \
  _sf=_fmt;                              \
  while (Pos("\n",_sf)>=0) {             \
    _s=strsplit(_sf,"\n");               \
    while (Pos("\t",_s)>=0) {            \
      _x=(1+_x/_tab_width_)*_tab_width_; \
      _s=strexch(_s, "\t", ""); }        \
    printfxy( _x, _y, _s, _val);         \
    _x=0;  _y-=8;                        \
  }                                      \
  while (Pos("\t",_sf)>=0) {             \
     _x=(1+_x/_tab_width_)*_tab_width_;  \
     _sf=strexch(_sf, "\t", ""); }       \
     if(_x>=96) {_x=0; _y-=8;}           \
     if(_y<0) {scrclr(); _y=56;}         \
  printfxy( _x, _y, _sf, _val);          \
}

//*********************************************
#define _NUL_  0
#define _BEL_  7
#define _BS_   8
#define _LF_  10
#define _SP_  32


char STDIN_PORT = S1;
//*********************************************

bool kbdhit() {
  return (NP_GetKeysPressed (STDIN_PORT, NPdevAddr));
}

//*********************************************
char cin() {
   char c=_NUL_;

   if (NP_GetKeyPress(STDIN_PORT, NPdevAddr, 50, c) ) return c;
   else
   return _NUL_;
}

//*********************************************

void NP_init(char port) {

   STDIN_PORT=port;
   SetSensorLowspeed(STDIN_PORT);
   NP_InitializeKeypad(STDIN_PORT, NPdevAddr);
   Wait(100);
}

//*********************************************

string getskbdraw(void) {
  string s;
   byte keycount;
   byte Keys[13];
   int  i, keysBits;
   
    s="";
    keysBits = NP_GetKeysPressed(STDIN_PORT, NPdevAddr);

    if  (NP_DecodeKeys (keysBits, Keys) > 0 ) {
      for (i=0; i<12; ++i) {
        if (Keys[i] == 1) {
               if ( i <= 9 ) {
              PlayTone(880,10);
              s = NumToStr(i);
              while(kbdhit());
          }
          if (i==10) {
              s = s+"*";
              PlayTone(440,4); Wait(5);
              }
          if (i==11) {
                   s = s+"#";
              PlayTone(220,3); Wait(4);
              }
        }
         }
      }
    return s;
}

//*********************************************

char getch(void) {
    char chr=_BEL_;
    string _str_="";
    unsigned long _time_;


    _time_=CurrentTick();
    TextOut(_cur_x_,_cur_y_,"_");
   
    while( _str_ =="") {
      Wait( 20);
      chr=_BEL_;
      _str_=getskbdraw();

      if ((CurrentTick()-_time_) >1000) {
        _time_=CurrentTick();
        if (_str_=="*")   {
          backspace();
          return _BS_ ;
        }
        else if (_str_=="#")  return _SP_ ;
        else if (_str_=="*#") {
          TextOut(_cur_x_,_cur_y_," ");
          printf("\n","");
          return _LF_ ;
        }
      }

      else if((_str_=="*")||(_str_=="#")||(_str_=="*#")) { _str_="";  }

      if(_str_!="") {
        chr=_str_[0];
        _time_=CurrentTick();
        if (Pos("*#",_str_)>=0) chr+=37;  // *#0 = 'U'...*#5 = 'Z'
        else
        if (Pos("*", _str_)>=0) chr+=17;   // *0 = 'A' ... *9 = 'J'
        else
        if (Pos("#", _str_)>=0) chr+=27;   // #0 = 'K' ... #9 = 'T'
        if (chr==91) chr='+';   // = *#6
        if (chr==92) chr='-';   // = *#7
        if (chr==93) chr='.';   // = *#8   // optional: '*'
        if (chr==94) chr=':';   // = *#9   // optional: '/'
      }
    }

    return chr ;
}

//*********************************************

string gets(string &input) {                 // C-like, echoes on screen
   char key;

   while(key != _LF_) {                      //  _LF_ = 10 = end of input
     key=getch();
     if (key>=' ') {
       printf("%c", key);                    // print character on screen
       input+=FlattenVar(key);               // append character to string
     }
     else if (key==_BS_)                     //  _BS_ =  8 = backspace
       strncpy(input,input,strlen(input)-1); // delete last string entry
     Wait(10);
   }
   return input;
}
//*********************************************

task main()           // main task:
{
  string input;

  NP_init(S1);

  printf("write your text!\n","") ;
  printf("*0=A #0=K *#0=U\n\n","");

  gets(input);
 
  printf("your input:\n%s",input);       // print again string for controlling


  while(1);
}


Code:
/************************************************************************/
/*                                                                      */
/* Program Name: NP-lib.h */
/* =============================                                        */

// modified by HaWe
/*                                                                      */
/* Copyright (c) 2010 by mindsensors.com                                */
/* Email: info (<at>) mindsensors (<dot>) com                           */
/*                                                                      */
/* This program is free software. You can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; version 3 of the License.              */
/* Read the license at: http://www.gnu.org/licenses/gpl.txt             */
/*                                                                      */
/************************************************************************/
/*
 * When        Who                      Comments
 * 10/10/10    Deepak Patil             Initial authoring.
 * 11/02/10    Matthew Richardson       adding functions: NP_DecodeKeys and
                                        NP_GetKeysPressed and cleaning up.
* 2012-11-18   HaWe                     changing  #defines, wait constants
 */

#ifndef _NP-lib_H_
   #define _NP-lib_H_
   
#define KEY_STATUS_REG 0x00
#define NPdevAddr 0xB4
 

char keyMap[] = { '4', '1', '7', '*', '5', '2', '8', '0', '3', '6', '9', '#' };

// Do not change the contents of these Group variables or the order.
byte Group1[] = { 0x2B, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0xFF, 0x02};
byte Group2[] = { 0x41, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F};
byte Group3[] = { 0x4A, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F};
byte Group4[] = { 0x52, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F};
byte Group5[] = { 0x5C, 0x0b, 0x20, 0x0C};
byte Group6[] = { 0x7D, 0x9C, 0x65, 0x8C};

void NP_i2cwrite(byte port, byte addr, byte reg, byte data)
{
  byte result = -1;             // default: error value
  byte cmdbuf[];               // register number holder
  int loop, n, nByteReady;

  ArrayBuild(cmdbuf, addr, reg, data);
   loop = STAT_COMM_PENDING;
  while ( loop == STAT_COMM_PENDING ) {
    loop = I2CStatus(port, nByteReady);
  }

  // when the I2C bus is ready, send the message you built
  n = I2CWrite(port, 0, cmdbuf);
  while (I2CStatus(port, nByteReady) ==  STAT_COMM_PENDING);
}



// read data from sensor register(s)
int NP_i2cread(byte port, byte addr, byte reg, byte cnt)
{
  int result = -1;             // default: error value
  byte outbuf[];               // here we will get data
  byte cmdbuf[];               // register number holder
  int             loop;
  byte            nByteReady = 0;

  ArrayBuild(cmdbuf, addr, reg);
  loop = STAT_COMM_PENDING;
  while (loop == STAT_COMM_PENDING) {
      loop = I2CStatus(port, nByteReady);
  }
  if(I2CBytes(port, cmdbuf, cnt, outbuf))
  {
    result = outbuf[0];       // read value
    if(cnt==2)
      result = result + outbuf[1]*256;
// if 2 registers (16 bit), then add the MSB part
  }

  return result;              // returns -1 if I2CBytes failed
}
 
 void NP_writeBytes(byte port, byte addr, const byte & Group[])
 {
  int n, nbytes;
  // Wait for the end of previously sent data
  while(I2CStatus(port, nbytes)==STAT_COMM_PENDING);
  byte WriteBuf[];
  ArrayBuild(WriteBuf, addr, Group);
  I2CWrite(port, 0, WriteBuf);
}

void NP_InitializeKeypad(byte port, byte addr) {
// the following sequence of bytes initialize the sensor's
// configuration for performance.

// This function must be called at the beginning of every power cycle
// (call it at the beginning of your program, after you initialize the port).

// Do not change the values below
// Or the order in which these values are written.
  NP_writeBytes(port, addr, Group2);
  NP_writeBytes(port, addr, Group3);
  NP_writeBytes(port, addr, Group4);
  NP_writeBytes(port, addr, Group5);
  NP_writeBytes(port, addr, Group1);
  NP_i2cwrite(port, addr, 0x7B, 0x0B);
  NP_writeBytes(port, addr, Group6);
}

bool NP_GetKeyPress(byte port, byte addr, int waitPeriod /* ms */, byte &keyHolder)
{
  int Touch;
  int Previous_Touch;
  int bit_test;
  int i, j;
  string a, msg, s;
  int w, cw;
  w = waitPeriod;  // <========================= ms!

  cw = 0;  // cumulative wait
  while(true)
  {

   Touch = NP_i2cread(port, addr, KEY_STATUS_REG, 2);
   Touch = Touch & 0x0FFF;     //Last 4 bits of byte 2 are not relevant

   int b;
   b = 0x01 << 11;

    if(Previous_Touch != Touch)
    {
      Previous_Touch = Touch;

        for ( j=0, i=0; j < 12; j++)
        {
          if ( Touch & b ) {
            keyHolder = keyMap[j];
            return true;
        }
        b = b >> 1;
      }
    }
    Wait(50);
    cw += 20;    // <================= 50
    if ( w != 0 && cw > w ) {
      return false;
    }
  }
  return false;
}

int NP_GetKeysPressed (byte port, byte addr)
{   //Returns a 12bit number containing the status of all 12 keys.
  int result;
  result=NP_i2cread(port, addr, 0x00, 2);
  result=result & 0x0FFF;
  return result;
}

int NP_DecodeKeys (int KeyBits, byte & Keys[])
{  //Bytes 0-11 of Array Keys contain the specific keys pressed.
    //Byte 12 contains the number of buttons pressed (returned by the function).
  Keys[12]=0;
  if (KeyBits>=2048){KeyBits-=2048;Keys[12]++;Keys[4]=1;} else{Keys[4]=0;}
  if (KeyBits>=1024){KeyBits-=1024;Keys[12]++;Keys[1]=1;} else{Keys[1]=0;}
  if (KeyBits>=512) {KeyBits-=512; Keys[12]++;Keys[7]=1;} else{Keys[7]=0;}
  if (KeyBits>=256) {KeyBits-=256; Keys[12]++;Keys[10]=1;}else{Keys[10]=0;}
  if (KeyBits>=128) {KeyBits-=128; Keys[12]++;Keys[5]=1;} else{Keys[5]=0;}
  if (KeyBits>=64)  {KeyBits-=64;  Keys[12]++;Keys[2]=1;} else{Keys[2]=0;}
  if (KeyBits>=32)  {KeyBits-=32;  Keys[12]++;Keys[8]=1;} else{Keys[8]=0;}
  if (KeyBits>=16)  {KeyBits-=16;  Keys[12]++;Keys[0]=1;} else{Keys[0]=0;}
  if (KeyBits>=8)   {KeyBits-=8;   Keys[12]++;Keys[3]=1;} else{Keys[3]=0;}
  if (KeyBits>=4)   {KeyBits-=4;   Keys[12]++;Keys[6]=1;} else{Keys[6]=0;}
  if (KeyBits>=2)   {KeyBits-=2;   Keys[12]++;Keys[9]=1;} else{Keys[9]=0;}
  if (KeyBits>=1)   {KeyBits-=1;   Keys[12]++;Keys[11]=1;}else{Keys[11]=0;}
   return Keys[12];
}

#endif


EDIT - Bugfix 1.2.:
getch() arbeitet jetzt wie bei "echtem" C und wartet auf eine Tastatur-Eingabe ohne ein Echo auf dem Bildschirm auszugeben.
Wird ein Bildschirm-Echo gewünscht, muss man selber dafür sorgen (per printf oder TextOut).


31. Okt 2012 17:42
Profil
Administrator
Administrator
Benutzeravatar

Registriert: 11. Jan 2006 21:01
Beiträge: 4347
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze
Beitrag Re: NXC: MS NumPad als alpha-numerische Tastatur (C-Konsole)
Version 2.0.:

Die C-konforme I/O console ist fertig! 8-) 8-) 8-)

Unterschieden wird zwischen "Zifferntasten" 0-9 und den beiden "Funktionstasten" * und # .
Als "gültige Eingabe" erhält man alle Ziffern 0-9 plus optional zusätzliche Funktionstaste(n) * oder # oder *# gleichzeitig.
Ebenfalls gewertet wird ein langer Tastendruck der Funktionstasten alleine oder in Kombination.

Ziffern-Tasten optional zusammen mit * oder # oder *# ergeben => Zahlen, Buchstaben oder Sonderzeichen
*0 bis *9 = A...J
#0 bis #9 = K...T
*#0 bis *#5 = U...Z
*#6= +
*#7= -
*#8= .
*#9= :
langer Druck auf * => Backspace
langer Druck auf # => Leerzeichen
langer Druck auf *# => Enter (Ende der Eingabe)

will man nicht auf einen Tastendruck warten, sondern nur registrieren, ob eine Taste zwischendurch mal "nebenher" gedrückt wurde,und erst dann auslesen, kann man die Funktion kbdhit() vorher abfragen:
Code:
if kbdhit() chr=getch();


Version 2.02:
neu: unterstützt jetzt auch gets(string) mit automatischem Echo auf dem Bildschirm:
Code:
// featuring C-like functions from <stdio.h>, <conio.h> :
//=======================================================
// int    getch()              // reads key from numpad, no echo on screen
// string gets(string)         // reads string from numpad + echo on screen
// char   (bool) kbdhit()      // tests if key hit on numpad, no return, no echo
// char   cin (no pipelining)  // reads single key from numpad, no echo on screen
// printf (fmtstring, variant) // displays formatted char, string, int, float

gets(string) ermöglicht es einen string einzulesen und gibt das Echo dabei automatisch auf dem Bildschirm aus. Die letzten Eingaben können mit Backspace [ *] rückgängig gemacht werden. Es wird solange in einen string-Puffer geschrieben, bis die Eingabe mit Enter [*#] abgeschlossen wird.

im Beispielprogramm (s. TOP ganz oben) wird dies demonstriert. Dazu ist alleinig nur diese eine Programmzeile nötig:
Code:
gets(input);

danach wird im obigen Beispielprogramm der eingegebene String nochmal zur Kontrolle angezeigt (allerdings fw-bedingt evtl. abgeschnitten).
Dateianhang:
Numpad Screen.jpg
Numpad Screen.jpg [ 10.37 KiB | 1198-mal betrachtet ]


Share and enjoy!


5. Nov 2012 17:49
Profil
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Auf das Thema antworten   [ 2 Beiträge ] 

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 11 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
Impressum Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Deutsche Übersetzung durch phpBB.de