elabor.vom-kuhberg.de

Man kann einen Arduino NANO dazu benützen ein universelles I2C-Command-Line-Tool
über einen Virtuellen COM Port mit 9600 Bit/sec zur Verfügung zu stellen
I2C>
Erlaubt sind dann die folgenden Befehle
SS I2C-Start
xx I2C-Write a Byte 00..FF
RA I2C-Read a Byte with ACK
RN I2C-Read a Byte with NO ACK
Rx I2C-Read x Byte x=0..F, also 1..16 Byte
PP I2C-Stop
SCANScan all Adresses on BUS 00..7F
I2C_CmdLineInterface.ino     hat 195 Zeilen bzw. 7180 Bytes
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
 // Programm: I2C_CmdLineInterface.ino
// Sprache:  Arduinio C++
// Hardware: Arduino Nano     
//                    o+5V---o------o----o +5V
//                           |      |
//                          4k7    4k7
//                           |      |
//                   -o A5---o-----------o SDA
//                                  |
//                   -o A4----------o----o SCL
//
//                   -oGND---------------o GND
// Version:  0.1 2013-12-30
// Autor:    R.Hoermann RBS Ulm
// Homepage: arduino.vom-kuhberg.de =>Projekte/I2C_CLI

#include <Wire.h>                       // Einbindung I2C-Library

int    i_key;                           // Variable fuer Tasten
String s_cmd;                           // auszufuehrendes Kommando
String s_i2c;                           // 2 Char I2C-Befehl
String s_old="";                        // Last Command
bool   b_slow=false;                    // I2C im Slow-Modus
bool   b_i2c_start=false;               // I2C Start-Bedingung noetig
int    i_ret;                           // Return value;

//------------------------------------------
// // System Initialisierung
//------------------------------------------
void setup()
{
  
Serial.begin(9600);                   // Serial Config
  
Wire.begin();                         // Initialisierung I2C-Bus(2 Wire)
  
Serial.write("I2C>");                 // Prompt ausgeben
}

//-----------------------------------------------------
// MAIN Program Loop runs until Systemreset or Poweroff
//-----------------------------------------------------
void loop()
{
  if (
Serial.available() > 0)           // liegt ein Tastendruck an
  
keyhandle(); }                      //   dann verarbeiten
}

//------------------------------------------
// Scan I2C / Two Wire Bus for activ devices
// return  Number of aktive devices
//------------------------------------------
int wire_Scan()
{
  
int i_devadr;                         // Master-Adresse des I2C-Device 0..127
  
int i_res;                            // Resultat des 'Anklopfens' bei einer Adr
  
int i_cnt=-1;                         // Zaehler fuer gefundene Devices
  
for (i_devadr=8;i_devadr<127;i_devadr++)
  {
    
Wire.beginTransmission(i_devadr);   // Bei der gegebenen Adresse 'anklopfen'
    
i_res=Wire.endTransmission();       // i_res==0 Adresse ist aktiv
    
if (i_res==0)                       // Wenn Adresse aktiv diese ausgeben
    
{
      if (
i_devadr16){Serial.write('0');}
      
Serial.print(i_devadr,HEX);
      
Serial.println("h OKAY");
      
i_cnt++;
    }
  }
  return 
i_cnt;
}


//----------------------------------------
// Get and Interpret all Serial Keys
//----------------------------------------
void keyhandle()
{
  
i_key Serial.read();                // Anliegende Taste einlesen
  
if (i_key==or i_key==127)           // Backspace bzw DEL Taste beruecksichtigen
  
{
    
int i_cl=s_cmd.length()-1;
    
s_cmd=s_cmd.substring(0,i_cl);
    
Serial.write(8);Serial.write(32); Serial.write(8); i_key=0;
  }
  if (
i_key >90){i_key-=32;}            // klein in GROSS-Buchstaben
  
if (i_key>=32)                        // Gueltiger Tastcode: alle ASCII >=32
  
{s_cmd=s_cmd+char(i_key); Serial.write(i_key);}
  if (
i_key==13)                        // Wenn ENTER Taste dann Commando ausfuehren
  
{CLI_exec(); s_cmd=""Serial.print("I2C>"); }
}

//----------------------------------------
// Show a Command-Help on Serial Terminal
//----------------------------------------
int Help()
{
  
Serial.println("SS      Start");
  
Serial.println("PP      Stop");
  
Serial.println("RA      Read with Acknowledge");
  
Serial.println("RN      Read NO   Acknowledge");
  
Serial.println("Rx      Read x=0..F Read 1..16 Byte with Acknowledge");
  
Serial.println("XX      00..FF  Data Byte to Write");
  
Serial.println("SM      00 00..FF FF  Sleep 0..65000 ms");
  
Serial.println("SLOW    SLOW    Clocktakt=1sec");
  
Serial.println("SCAN    Scan all I2C-Devices on BUS");
  
Serial.println("REP     Repeat last Command");
  
Serial.println("Examples:");
  
Serial.println("SS 40 55 PP       =>Set  PCF8574 to 01010101 ");
  
Serial.println("SS 48 44 PP R4 PP =>Read all 4 Channels from PCF8591 at Adr 48");
  return 
0;
}

//----------------------------------------
// 0..9 bzw. A..F in Decimal-Zahl wandeln
//----------------------------------------
int hex2int(char c)
{
  
i_ret=-1;
  if ((
c>='0') & (c<='9')){return c-48;}
  if ((
c>='A') & (c<='F')){return c-55;}
  return 
i_ret;
}

//----------------------------------------
// 00..FF in Decimal-Zahl wandeln
//----------------------------------------
int h2int(String sh)
{
  
int i_nh,i_nl;
  
int i_ret=-1;
  
i_nh=hex2int(sh[0]);
  if (
i_nh>=0)
  {
    
i_nl=hex2int(sh[1]);
    if (
i_nl>=0){return 16*i_nh+i_nl;}
  }
  return -
1;
}

//----------------------------------------
// Execute Command-Line Commands on ENTER
//----------------------------------------
int CLI_exec()
{
  
int  i_val,i_devadr,i_rn;
  
long i_msh,i_msl;
  
long i_ms;
  
Serial.println();
  if(
s_cmd=="?")    {Help();      return 0; }
  if(
s_cmd=="SLOW") {b_slow=true; return 0; }
  if(
s_cmd=="SCAN") {wire_Scan(); return 0; }
  if(
s_cmd=="REP")  {s_cmd=s_oldSerial.print("Repeat last Command:"); Serial.println(s_cmd);}
  
s_old=s_cmd;                          // Zuletzt ausgefuehrtes Commando merken
  
while (s_cmd.length()>0)              // Sub-Commandos abarbeiten
  
{
    
i_ret=-1;
    
s_i2c=s_cmd.substring(0,2); s_cmd=s_cmd.substring(3);
    
Serial.print(s_i2c);
    
i_val=h2int(s_i2c);
    if (
i_val>=0)
    {
      if (
b_i2c_start)
      { 
Serial.print(" DevAdr "); b_i2c_start=falseWire.beginTransmission(i_val); i_devadr=i_val; }
      else
      { 
Serial.print(" WrData "); Wire.write(i_val); }
      
Serial.println(i_val); i_ret=0;
    }
    if (
s_i2c=="SS"){ Serial.println(" Start"); Wire.begin(); i_ret=0b_i2c_start=true;}
    if (
s_i2c=="PP"){ Serial.println(" Stop");  Wire.endTransmission();  i_ret=0;}
    if (
s_i2c=="RN"){ Serial.println(" Read NAK ="); Wire.requestFrom(i_devadr,1); i_val=Wire.read(); Serial.println(i_val);  i_ret=0;}
    if (
s_i2c=="RA"){ Serial.println(" Read ACK ="); Wire.requestFrom(i_devadr,1); i_val=Wire.read(); Serial.println(i_val);  i_ret=0;}
    if (
s_i2c[0]=='R')                  // Repeat Reading 
    
{
      
i_rn=hex2int(s_i2c[1])+1;         // Anzahl der Repeats
      
if (i_rn>0)
      {
        
Serial.print(" Reading "); Serial.print(i_rn); Serial.print(" Bytes from Adr "); Serial.print(i_devadr,HEX); Serial.print(": ");
        
Wire.requestFrom(i_devadr,i_rn);
        for(
int i=0;i<i_rn;i++){ i_val=Wire.read(); Serial.print(i_val,HEX); Serial.write(' ');} Serial.println();
        
i_ret=0;
      }
    }
    if (
s_i2c=="SM")                    // Sleep Commando
    
{
      
Serial.print(" Sleep ");
      
i_msh=h2int(s_cmd.substring(0,2)); s_cmd=s_cmd.substring(3);
      
i_msl=h2int(s_cmd.substring(0,2)); s_cmd=s_cmd.substring(3);
      
i_ms=256*i_msh+i_msl;
      
Serial.print(i_ms); Serial.println(" ms");
      
delay(i_ms);
      
i_ret=0;
    }
    if (
i_ret!=0)                       // KEIN gueltiges Sub-Commando gefunden
    
Serial.print(" Unknown "); Serial.println(s_i2c); }
  }
  return 
i_ret=0;
}