Projekt i-Sobot - Hilfe gesucht

Es geht um ein Projekt mit dem kleinen Roboter i-Sobot und einem Arduino Pro Mini.

Ich habe die Programme von "knuckles904" aus seinem Thread verwendet und versucht den i-Sobot damit anzusprechen:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1237771631/0

Ich verwende allerdings einen 16MHz, 5V 328 ProMini Board und "knuckles904" das ältere 8MHz 3,3V Board.

Ich habe zusammen mit User "Poldi" versucht das Ding zum Laufen zu bekommen.

Zum Testen erstmal nur ein Programm, was nur ein Signalkommando der FB emuliert und über die IR Sendediode zum i-Sobot schickt.

Leider tut der Roboter nichts. Er funktioniert nur mit seiner Fernbedienung einwandfrei. In dem ist eine identische Sendediode eingebaut, wie am Arduino Board.

Wir haben mit einem Speicher-Oszi das Signal der beiden IR Sender-Dioden überprüft.

Die Periodendauer des Signalteils von der Original Fernbedienung des i-Sobots hat 25,5 µs. Die Periodendauer des Signalteils vom Arduino Pro Mini mit dem Code von "knuckles904" ist 33,6 µs.

Wir haben verschiedene Vorteiler (prescaler) Werte eingesetzt in die cpp Datei, aber die Periodendauer hat sich nicht verändert.

Wir haben nach jeder Änderung die Datei gespeichert, die .o Datei gelöscht, neu kompiliert und dann neu zum Arduino übertragen.

Das Ergebnis war jedesmal 33,6 µs. Wir wissen leider nicht woran das liegt.

Es wäre super, wenn jemand eine Lösung dafür wüsste und uns helfen könnte.

Vielen Dank. Grüße, Jens

Ja, kann mich Crazydoc nur anschließen. Es wäre echt schön, wenn da mal jemand drauf schauen würde. Mit den ganzen Timings und dem “zusammenbasteln” des IR-Protokolls komme ich nicht so zurecht…

Hier die aus dem englischen Beitrag und von uns verwendeten Codes:

Isobot.cpp (Prescaler-Funktion bei den vielen “///” nahe dem Anfang zu finden).

#include "WProgram.h"
#include "Isobot.h"
//Isobot IR decoder and Controller
//Written by Miles Moody
//Isobot IR protocol works as follows
//carrier freq of about 38khz
//header pulse of 2550 micros high
//22 data bits=4 for channel number, 18 for button number
//highs carry no info and are 550 micros each
//lows are logic 0 if 550 micros, logic 1 if 1050 micros
//at end of stream or in between, 205 millis low
//NOTE: my ir reciever pin goes low when it detects high signal
//      and stays high when nothing is being recieved
//      that could cause some confusion

//-------------------info about bits-------------------------------
#define totallength 22            //number of highs=bits 4 channel +18 command
#define channelstart 0
#define commandstart 4       //bit where command starts
#define channellength  4
#define commandlength  18
//---------determined empirically--------------
#define headerlower 2300     //lower limit
#define headernom 2550       //nominal
#define headerupper 2800     //upper limit
#define zerolower 300
#define zeronom 380          //nominal
#define zeroupper 650
#define onelower 800
#define onenom 850          //nominal
#define oneupper 1100
#define highnom 630
//global vars (might be needed)
bool bit2[22]={};
//Constructors
Isobot::Isobot(int txpin){
    pinMode(txpin, OUTPUT);
    TXpin=txpin;
}
Isobot::Isobot(int txpin, int rxpin){
    pinMode(txpin, OUTPUT);
    pinMode(rxpin, INPUT);
    TXpin=txpin;
    RXpin=rxpin;
}
//functions
void Isobot::oscWrite(int time){                     ////////////////////////////////////////////////////////////
    for(int i = 0; i < (time / 26) - 1; i++){          //prescaler at 26 for 16mhz, 52 at 8mhz, ? for 20mhz
    digitalWrite(TXpin, HIGH);
    delayMicroseconds(13);
    digitalWrite(TXpin, LOW);
    delayMicroseconds(13);
  }
}

unsigned long Isobot::power2(int power){    //gives 2 to the int(power)
    unsigned long integer=1;                //apparently both bitshifting and pow functions had problems
  for (int i=0; i<power; i++){              //so I made my own
    integer*=2;
  }
  return integer;
}

void Isobot::buttonwrite(unsigned long integer){      //must be full integer (channel + command)
  ItoB(integer, 22);                               //must have bit2[22] to hold values
  oscWrite(headernom);
  for(int i=0;i<totallength;i++){
    if (bit2[i]==0)delayMicroseconds(zeronom);
    else delayMicroseconds(onenom);
    oscWrite(highnom);
  }
  delay(205);
}

void Isobot::buttonwrite(unsigned long integer, int numoftimes){      //same as above but repeats numoftimes
  ItoB(integer, 22);                                      
  for (int n=0;n<numoftimes;n++){
    oscWrite(headernom);
    for(int i=0;i<totallength;i++){
        if (bit2[i]==0)delayMicroseconds(zeronom);
        else delayMicroseconds(onenom);
        oscWrite(highnom);
    }
  delay(205);
  }
}

void Isobot::ItoB(unsigned long integer, int length){                //needs bit2[length]
  for (int i=0; i<length; i++){
    if ((integer / power2(length-1-i))==1){
      integer-=power2(length-1-i);
      bit2[i]=1;
    }
    else bit2[i]=0;
  }
}

unsigned long Isobot::BtoI(int start, int numofbits, boolean bit[]){    //binary array to integer conversion
  unsigned long integer=0;
  int i=start;
  int n=0;
  while(n<numofbits){
    integer+=bit[i]*power2((numofbits-n-1)); //same as pow()
    i++;
    n++;
  }
  Serial.println();
  return integer;
}

unsigned long Isobot::receivecode(){    //receives single code then puts into ulong code
  boolean bit[totallength];      //should be 22 data bits 0-3 are channel code 4-21 are command bits
  unsigned long plen[totallength];  //pulse length for debugging
  int i=0;    //bit number
  boolean channel;//channel A=0 channel B=1
  unsigned long commandcode;  //18bits
  unsigned long totalcode;    //22bits
  
  Serial.println("Waiting...");
  while(digitalRead(RXpin)==HIGH){}//kill time till header pulse comes in
                                   //RX is low here
  for(i=0; i<totallength; i++){
    plen[i]=pulseIn(RXpin, HIGH); //get length of HIGH pulses (yea mine works backwards)
  }
  
  for (i=0; i<totallength; i++){                  //sets bits based on pulselength of HIGHs
    if (plen[i]<zeroupper && plen[i]>zerolower)bit[i]=0;
    else if (plen[i]<oneupper && plen[i]>onelower)bit[i]=1;
  }
  if (bit[0]==0)channel=0;              //calculates channel based on highest bit value
  else if (bit[0]==1)channel=1;
  //commandcode=BtoI(commandstart, commandlength, bit);       //calculates just commandcode
  //totalcode=BtoI(channelstart, totallength, bit);           //calculates totalcode
  /*                                                   //uncomment code for signal analysis
  Serial.println("p len\thi/lo");                //prints pulse length and bit state
  for (i=0; i<totallength; i++){
    Serial.print(plen[i]);
    Serial.print("\t");
    Serial.println(bit[i], DEC);
  }
  */
  /*
  Serial.print("ch\tb code\t code\n");  //prints channel, buttoncode, channelcode
  if (channel==0)Serial.print("A\t");
  else Serial.print("B\t");
  Serial.print(commandcode);
  Serial.print("\t");
  Serial.println(totalcode);
  */
  /*
  ItoB(commandcode, 18);  //checks ItoB
  ItoB(totalcode, 22);
  for(i=commandstart; i<totallength; i++) Serial.print(bit2[i], DEC);
  Serial.println();
  for(i=0; i<totallength; i++) Serial.print(bit2[i], DEC);
  Serial.println();
  */
  for(i=0; i<totallength; i++) plen[i]=0;
  delay(1000);                    //delays to cut repeated
  return(BtoI(channelstart, totallength, bit));
}

Weiter geht es im nächsten Post:

Hier ist die Isobot.h:

//Isobot IR Decoding and Sending Library
//Written by Miles Moody
//Free and open to the public

#ifndef Isobot_h
#define Isobot_h

#include "WProgram.h"
#include "WConstants.h"

class Isobot{
      public:
             Isobot(int txpin);
             Isobot(int txpin, int rxpin);
             unsigned long receivecode();
             void buttonwrite(unsigned long integer);
             void buttonwrite(unsigned long integer, int numoftimes);
      private:
              int TXpin;
              int RXpin;
              void oscWrite(int time);
              unsigned long power2(int power);
              void ItoB(unsigned long integer, int length);
              unsigned long BtoI(int start, int numofbits, boolean bit[]);
              
};

//-------------------buttoncodes-------------------------
#define forward      898819
#define backward     964611
#define sideright    703491
#define sideleft     637699
#define fleft        1030403
#define fright       571907
#define bleft        834819
#define bright       900611
#define fclockwise   966403
#define fcounter     1032195
#define bclockwise   573699
#define bcounter     639491
#define headleft     907015
#define headright    775948
#define leanforward  841478
#define leanback     1038081
#define lpunch       922368
#define r12          661248
#define lchop        858368
#define sidechopl    663040
#define combopunch   597248
#define rpunch       988160
#define rchop        924160
#define l12          792576
#define sidechopr    728832
#define lbackhand    529664
#define doublechop   989952
#define doublebackhand 925952
#define slapping     860160
#define rbackhand    595456
#define upperchop    531456
#define roundhousel  991744
#define roundhouser  533248
#define forwardkickl 599040
#define forwardkickr 664832
#define sidekickl    730624
#define roundhouselr 666624
#define forwardkicklr 732416
#define combokick    798208
#define sidekickr    796416
#define backkickl    927744
#define backkickr    993536
#define highkickl    864000
#define highkickr    995328
#define splits1      536832
#define guardl       602624
#define guardr       668416
#define doubleguard1 734208
#define doubleguard2 800000
#define dodgel       865792
#define dodger       931584
#define duck         604160
#define swayback     669952
#define upblock      735744
#define splits2      801536
#define comboblock   867328
#define zero         1034752
#define homeposition 775424
#define soundoff     840451
#define affirm       540416
#define disagree     803328
#define goodmorning  934912
#define greet1       1000704
#define greet2       608000
#define greet3       739328
#define greet4       805120
#define bye1         870912
#define bye2         936704
#define bye3         1002496
#define bye4         544000
#define bye5         542208
#define respect      869120
#define thanks1      609792
#define thanks2      675584
#define love1        872704
#define love2        938496
#define love3        1004288
#define standupfront 933120
#define standupback  998912
#define excited1     743168
#define excited2     874496
#define excited3     940288
#define excited4     618752
#define party        677376
#define amazed       750336
#define regret1      547584
#define regret2      744960
#define regret3      810752
#define worry        679168
#define pain1        1007872
#define pain2        615168
#define beg1         942080
#define beg2         880128
#define merry        552960
#define hilarious    1013504
#define hidenseek    613376
#define youlike      682752
#define mystery5     748544
#define tipsy        814336
#define tickleme     686080
#define tiredfeet    751872
#define needabreak   817664
#define wave1        883456
#define wave2        949248
#define applause     947712
#define mystery6     945920
#define toosexy      1015040
#define clink        556544
#define relax        753664
#define soccer1      885248
#define soccer2      600832
#define soccer3      535040
#define lift         819456
#define countonme    951040
#define articulation 1016832
#define showoff1     558336
#define showoff2     624128
#define showoff3     689920
#define showoff4     821248
#define cominthrough 887040
#define catch        1006080
#define pose1        771840
#define pose2        903168
#define pose3        968960
#define mystery1     684544
#define mystery2     816128
#define mystery3     881920
#define mystery4     549376
#define forwardsomersault  952832
#define headstandexercises 1018624
#define exercises    560128
#define airdrum      625920
#define airguitar    691712
#define randomperformance1 954624
#define randomanimal   627712
#define tropicaldance  825088
#define giantrobot     956416
#define western        1022208
#define randomperformance2  629504


#endif

weiter ->

So und nun noch der eigentliche Test-Code welchen wir nochmal reduziert hatten (oben Original - unten die Test-Version)

#include <Isobot.h>

Isobot bot(7);
unsigned long time1, time2;

void setup(){
time1=time2=millis();
pinMode(13, OUTPUT);
}

void loop(){
if(millis()>(5000+time1)){
digitalWrite(13, HIGH);
bot.buttonwrite(homeposition,3);

time1=millis();
digitalWrite(13,LOW);
}

if(millis()>(20000+time2)){
digitalWrite(13,HIGH);
bot.buttonwrite(rpunch,3);

time2=time1=millis();
digitalWrite(13,LOW);
}
}

#include <Isobot.h>

Isobot bot(7);
unsigned long time1, time2;

void setup(){
//time1=time2=millis();
pinMode(13, OUTPUT);
}

void loop(){
//if(millis()>(5000+time1)){
digitalWrite(13, HIGH);
bot.buttonwrite(homeposition,3);

//time1=millis();
delay(1000);
digitalWrite(13,LOW);
delay(1000);
//}

//if(millis()>(20000+time2)){
digitalWrite(13,HIGH);
bot.buttonwrite(rpunch,3);

//time2=time1=millis();
digitalWrite(13,LOW);
//}
}

Egal, welche Funktion wir den Bot haben ausführen lassen, nichts tat sich, wenn die Signale aus dem Arduino und nicht aus der Fernbedienung kamen. Laut englischem Forum hätten wir nur den Prescaler ändern müssen.

Sind gespannt auf Eure Meinungen dazu.

Lieben Gruß
Poldi

So, als Info für alle die hier mal vorbeigeschaut haben:

Da wir es mit dem Arduino 328 16 Mhz Pro Mini Board nicht geschafft haben, den Code zum Laufen zu bekommen, habe ich mir noch das 8 MHz 168 Pro Mini Board gekauft.

Das hat auch knuckles904 verwendet.

Und welch Überraschung: Es funktioniert, wie es soll! :smiley:

Also alle die das auch basteln wollen und nicht den Code anpassen können, holt Euch das alte Board!

Schöne Feiertage Euch allen.

Grüße,
Jens