樹莓派 0W 狂想曲︰ 木牛流馬《界面》

如果只是將

W!o+ 的《小伶鼬工坊演義》︰ 一窺全豹之系統設計《關鍵》

固然我們現今可以閱讀 GrovePi 韌體的原始碼,

# GrovePi V1.2.5 韌體 I2C 讀寫流程骨幹

33 int cmd[5];
34 int index=0;
35 int flag=0;

68 void setup()
69 {
70     // Serial.begin(38400); // start serial for output
71     Wire.begin(SLAVE_ADDRESS);
72
73     Wire.onReceive(receiveData);
74     Wire.onRequest(sendData);
75         attachInterrupt(0,readPulseDust,CHANGE);
76 }

79 void loop()
80 {
81   long dur,RangeCm;
82   if(index==4)
83 {
84   flag=1;
85   //IR reciever pin set command
86   if(cmd[0]==22)
87      IR.Init(cmd[1]);
88
89   //Grove IR recieve command
90   else if(cmd[0]==21)
91   {
92      if(IR.IsDta())
93       {
94          int length= IR.Recv(dta);
95          b[0]=1;
96          for(i=0;i<20;i++)
97              b[i+1]=dta[i];
98       }
99   }
100
101 //Digital Read
102 else if(cmd[0]==1)
103   val=digitalRead(cmd[1]);
104 //Digital Write
105 else if(cmd[0]==2)
106   digitalWrite(cmd[1],cmd[2]);

646 void receiveData(int byteCount)
647 {
648     while(Wire.available())
649      {
650       if(Wire.available()==4)
651        {
652         flag=0;
653         index=0;
654                 run_once=1;
655        }
656         cmd[index++] = Wire.read();
657       }
658 }

660 // callback for sending data
661 void sendData()
662 {
663   if(cmd[0] == 1)
664     Wire.write(val);
665   if(cmd[0] == 3 || cmd[0] == 7 || cmd[0] == 56)
666     Wire.write(b, 3);
667   if(cmd[0] == 8 || cmd[0] == 20)
668     Wire.write(b, 4);
669   if(cmd[0] == 30)
670     Wire.write(b, 9);
671   if(cmd[0] == 40)
672     Wire.write(dht_b, 9);
673
674   if(cmd[0]==21)
675    {
676     Wire.write(b,21);
677     b[0]=0;
678    }
679   if(cmd[0]==dust_sensor_read_cmd)
680    {
681     Wire.write(b,4);
682         dust_latest=0;
683         cmd[0]=0;
684    }
685   if(cmd[0]==encoder_read_cmd)
686    {
687     Wire.write(enc_val,2);
688     enc_val[0]=0;
689         cmd[0]=0;
690    }
691   if(cmd[0]==flow_read_cmd)
692    {
693     Wire.write(flow_val,3);
694     flow_val[0]=0;
695         cmd[0]=0;
696    }
697
698 }


,追跡其上裝置的驅動始末,甚至可以創寫新的可連接設備。但思『架構拼圖』時,『全貌』是『關鍵』,一時過細恐泥。況且通常『應用軟體界面』 API ,實有多種多層

……

 

文字略作修改,以『GoPiGo』取代『GrovePi』,編輯新『韌體』原始碼︰

# GoPiGo fw_ver_16.ino 韌體 I2C 讀寫流程骨幹
# line 130
volatile int cmd[5],index=0,bytes_to_send=0; //I2C Message variables
byte payload[21];
unsigned char dta[20];

# line 266
//Setting up the GoPiGo
void setup()
{
    if (debug) //Enable the serial port on the GoPiGo
    {
        Serial.begin(19200);
        Serial.print("Ready");
    }

    for(int i=0;i<10;i++)
        hw_version=analogRead(7);

    if(hw_version<790)
    {
        motor2_control_pin2=13;
        right_led_pin=5;
        left_led_pin=10;
        voltage_pin=0;
    }
    attachInterrupt(0, step1, RISING); //Attach the encoders to an ISR to keep track of the wheel rotations
    attachInterrupt(1, step2, RISING);

    pinMode(motor1_control_pin1, OUTPUT); //Attach motor direction control pins
    pinMode(motor1_control_pin2, OUTPUT);
    pinMode(motor2_control_pin1, OUTPUT);
    pinMode(motor2_control_pin2, OUTPUT);
    // pinMode(left_led_pin, OUTPUT); //Attach motor direction control pins
    // pinMode(right_led_pin, OUTPUT);

    servo1.attach(5); //Set up the Servo
    //servo1.setMaximumPulse(3000);

    Wire.begin(GOPIGO_ADDR); //Set up I2C
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);

    speed1=speed2=spd;

    //IR.Init(A1);
    //Load the trim value for motor 2 from the EEPROM
    ep1=EEPROM.read(0);
    ep2=EEPROM.read(1);
    ep3=EEPROM.read(2);

    //Load the trim value of the first 2 bytes are the right signature
    if (ep1==ep_sig1 && ep2==ep_sig2)
        trim_val=ep3;
    //Disable trim if the signature is not a match
    else
        trim_val=100;

    // digitalWrite(right_led_pin,HIGH);
    // digitalWrite(left_led_pin,HIGH);
    // delay(1000);
    // digitalWrite(right_led_pin,LOW);
    // digitalWrite(left_led_pin,LOW);
    }

# line 331
//Main program loop
//IMPORTANT NOTE: Set the cmd[0] to 0 to mark that the command has been executed
// Be careful with this, because for some commands like fwd() and bwd() you'll not want the motors to stop when the GoPiGo receives any command. So most of the commands are run only once but when commands like fwd() , bwd() are running, cmd[0] goes back to the old state after the new commands are successfully run.

//FUNCTIONALITY NOTE:
// * servo::refresh() - takes .5 to 2.5 ms to complete
// * the motor interrupts have to be slower than the I2C interrupts. This has been a problem with I2C communication. The motor interrupts are of higher priority,
// so if I2C block communication is used, there is a chance of the motors interrupting them. Conflicts can still be there but very rare
void loop()
{
    //Update the speed by taking in account the trim value
    speed2_trim=int(speed2+(speed2*float(trim_val-100)/100));
    if (speed2_trim>255)
        speed2_trim=255;
    else if(speed2_trim<0)
        speed2_trim=0;

    analogWrite(motor1_speed_pin,speed1); //Write the speed to the motors
    analogWrite(motor2_speed_pin,speed2_trim);

    //LED encoder test (Manufacturing test: Not to be used by user)
    //Blink the left LED when the right wheel is rotated and the right LED when the left wheel is rotated
    if(cmd[0]==enc_test)
    {
        if(f1==1)
        {
            led_light(0,1);
            f1=0;
        }
        if(f2==1)
        {
            led_light(1,1);
            f2=0;
        }
        delay(200);
        led_light(0,0);
        led_light(1,0);
        }

# line 937
//Receive commands via I2C
void receiveData(int byteCount)
{
    while(Wire.available())
    {
        //When the buffer gets filled up with 4 bytes( the commands have to be 4 bytes in size), set the index back to 0 to read the next command
        if(Wire.available()==4)
        {
            index=0;
            if(timeout_f) //Refresh the communication time-out value
                last_t=millis();
        }
        cmd[index++] = Wire.read(); //Load the command into the buffer
    }
}

# line 953
// callback for sending data
volatile int ind=0;
void sendData()
{
     //if(timeout_f)
     // last_t=millis();
     //Sends 2 bytes back for the Ultrasonic read, voltage and firmware version
     if(bytes_to_send==2)
     {
         Wire.write(payload[ind++]);
         if(ind==2)
        {
             ind=0;
             bytes_to_send=0;
        }
     }
     else if(bytes_to_send==20)
     {
         Wire.write(payload,20);
         bytes_to_send=0;
     }
 // else if(bytes_to_send==21)
 // {
 // Wire.write(payload[ind++]);
 // if(ind==21)
 // {
 // ind=0;
 // bytes_to_send=0;
 // payload[0]=0;
 // }
 // }
     else// Send back the status flag
     {
         Wire.write(status_r);
     }
}

 

,實在沒有趣味。讀過者或認為敷衍了事,未讀過者也只得其一,都少了『比較法』學習之機會,何妨各自都能『讀樂樂』乎☆

 W!o+ 的《小伶鼬工坊演義》︰ 一窺全豹之系統設計《地圖》
 W!o+ 的《小伶鼬工坊演義》︰ 一窺全豹之系統設計《解讀》

W!o+ 的《小伶鼬工坊演義》︰ 一窺全豹之系統設計《童子問》

易童子問第一

乾,元亨利貞

童子問曰:「乾,元亨利貞」何謂也?

曰:眾辭淆亂,質諸聖。《彖》者,聖人之言也。

童子曰:然則《乾》無四德,而《文言》非聖人書乎?

曰:是魯穆姜之言也,在襄公之九年。

假使思考歐陽修為什麼寫《易童子問》?

歐陽修(1007年-1072年),字永叔,號醉翁、六一居士,諡文忠,北宋吉州廬陵(今屬江西省永豐縣)人。(歐陽修生平請參考維基百科

所著《易童子問》三卷,收錄於《歐陽文忠公集》(或簡稱《文忠集》)第七十六至七十八卷,以問答的方式表達其對於《易經》的一些見解。每個問題都以「童子問」做為開始。

文忠公是第一位對於《十翼》以及諸如「四元德」等傳統見解提出質疑與抨擊的大儒,而這些見解也影響了後世許多學者,甚至得到近現代許多學者考證的支持。

除了較為知名的《易童子問》三卷之外,易學網另外也收錄《文忠集》中其他與《易經》相關的論述,以完整呈現歐陽修對《易經》所提出的見解。

,難到不因懷疑也!『聖人』也是『人』??果能『全知』乎!!

今想 GrovePi 之『軟體架構』,當真『奇怪』耶︰

【為什麼需要 Dummy Byte ?】

dataformat

因為 SMBus 的

I2C Access Functions

long[] read_i2c_block_data( int addr, char cmd )
Block Read transaction.

write_i2c_block_data(int addr, char cmd,  long vals[])
Block Write transaction.

,需要『 char cmd 』參數!所以

………