At the forefront of Artificial Intelligence
  Home Articles Reviews Interviews JDK Glossary Features Discussion Search
Home » Articles » Robotics » Machine Learning

Machine learning (2 x 16F877)

By Bert van Dam

Nothing is more fascinating than learning machines. Well, except of course... never mind. Anyway, this observation is about a machine (pic) learning a sequence from another machine (pic), without any human intervention and with no more feedback than a percentage correct. One pic takes a random sequence, and the other has to learn what this sequence is. In the run in the screen shot below the correct sequence (1-3-2-4) was learned after 44 tries. After that the student pic answered correct 100% of the time.

The sequence consists of four steps. All possible combinations of 1,2,3 and 4 are allowed. So 1-2-3-4 is permitted, but so is 2-2-2-2. Anything goes, as long as it consists of four steps. The sequence is represented by LEDs. For example sequence 1-1-1-4 would mean flash LED 1 three times and LED 4 one time. The students guesses using his four LEDs. The teacher has four LDR's to detect the student's sequence. Both pics are connected by usart serial so the teacher can relay to the student the score for his attempt (0 - 100% correct).

So, how does the learning process work. The student has a brain (an array in eeprom memory) which can hold 5 different possible solutions. Each solution has a fitness. Fitness in this case means the number of correct positions (table below is just an example).

 serial# position 1 position 2 position 3 position 4 fitness
 1
1
1
2
3
 2
 2
1
3
4
4
 3
 3
2
3
2
4
 3
 4
3
4
3
4
 1
 5
4
4
4
1
 0

At each run the program will first check whether a 100% correct solution is available in the brain . If so it will select that solution.

  t = 0
  for 5 loop
    t = t + 1
    MemoryGet(t,6)
    if answer == 4 then
      UitTabel = t
      MemoryGet(UitTabel,2)
      keuze1 = answer
      MemoryGet(UitTabel,3)
      keuze2 = answer
      MemoryGet(UitTabel,4)
      keuze3 = answer
      MemoryGet(UitTabel,5)
      keuze4 = answer
    end if
  end loop

If such a solution is not available it will select a solution from it's brain (90% chance) or make up a random solution (10% chance). At this point it is clear that the solution from the brain is incorrect, so the program will make a small change to the solution (90% chance) if it came indeed from the brain. This small change is called mutation.

if UitTabel == 0 then
    -- make a choice from the brain (90%)or make up an
    -- answer on the spot (10%)
    selectie = random_byte 
    if selectie > 230 | FirstRun == 1 then
      -- select 4 random numbers in the range 1,2,3,4     
      RandomNumber
      keuze1 = answer   
      RandomNumber
      keuze2 = answer   
      RandomNumber
      keuze3 = answer   
      RandomNumber
      keuze4 = answer   
      FirstRun = 0
    else
      -- random selection from the brain 
      RandomNumber
      UitTabel = answer
      MemoryGet(UitTabel,2)
      keuze1 = answer
      MemoryGet(UitTabel,3)
      keuze2 = answer
      MemoryGet(UitTabel,4)
      keuze3 = answer
      MemoryGet(UitTabel,5)
      keuze4 = answer
                  
      -- make a random mutation (90 % chance)
      selectie = random_byte 
      if selectie < 230  then
        -- reset UitTabel because this is now a new solution
        UitTabel = 0
        RandomNumber
        NewValue = answer
        RandomNumber
        if answer == 1 then keuze1 = NewValue end if
        if answer == 2 then keuze2 = NewValue end if
        if answer == 3 then keuze3 = NewValue end if
        if answer == 4 then keuze4 = NewValue end if
      end if
    end if
  end if

The solution selected (or made) is shown to the teacher using the LEDs. The feedback, being the percentage correct is received through the usart serial link. If the solution was retrieved from the brain without any modifications the received fitness is simply re-stored into the brain, overriding the fitness already there. If the solution is new, or retrieved from the brain but then modified, the fitness is compared to the other fitnesses already in the brain. If the new one is better then one of the old ones the solution as well as the fitness are added, overwriting a worse solution. This means the contents of the brain is slowly but constantly improving.

if UitTabel == 0 then
    -- if this was a new choice see if a worse one exists in the brain 
    -- table and replace that one
    t = 0
    for 5 loop
      t = t + 1
      MemoryGet(t,6)
      if answer < correctCounter then
        MemoryPut(t,2,keuze1)
        MemoryPut(t,3,keuze2)
        MemoryPut(t,4,keuze3)
        MemoryPut(t,5,keuze4)
        MemoryPut(t,6,correctCounter)
      end if
    end loop
  else
    -- this is an existing selection, so modify the fitness in  the brain
    MemoryPut(UitTabel,6,correctCounter)
  end if

Now the program will loop.

Two things are noteworthy:

  1. Even if the correct solution is shown to the teacher the reported percentage correct is re-stored in the brain.
  2. Even when a wrong solution is selected from the brain in 10% of the cases no mutation is taking place.

These two 'deviations from logic' are necessary to maintain flexibility. The self-learning mechanism is geared towards flexible adaptivity to the environment. Learning systems like this are best used in changing environments. This means that if the correct answer is changed at any time (even after the student has successfully learned the correct answer) the program is flexible enough to immediately detect this and start learning the new sequence. These setting represent a trade off between learning fast the first time and learning fast upon change. Feel free to experiment and draw your own conclusions.

The 10% chance of selecting a totally random solution is to fill an empty brain gradually, and more importantly to prevent the program from getting stuck in a local, but not global, optimum.

This screen shot is from a prototype of this brain. The prototype brain functions exactly the same as the one in the pic. The red line in the graph shows the correctness of each answer (which varies quite a lot, but as soon as it hits '4 correct' it stays there), the purple line is the average correctness. It shows that the proper sequence was changed twice, and both times the program was quick to recuperate and learn the new sequence. And these changes were quite dramatic, from 1-2-3-4 to 1-1-2-4 to 4-4-3-3. That is the true power of learning machines!

The breadboard looks like this. The long wires are from the Wisp628 in circuit programmer. Note the yellow wire connecting the pin 1's of both pics. This way both pics restart when one of them gets a new program, and both restart when the programmer is switched to pass through mode. This makes sure that both programs run synchronized. The switch on the right hand side, with the red LED, is simply the on/off switch. Note that the LED-LDR combo's are not shielded against ambient light. If you program during the day shielding may be required, even though auto calibration is incorporated into the software.

Based on the following schematics (programmer wires and the yellow pin1-pin1 line are not shown):

The Visual Basic program which displays the progress of the student-teacher relationship is not required. It only displays data and has no influence on the learning process. The visualization is very nice however, so you can download the source here. Obviously you need Visual Basic to run the source.

The pic programs follow this sequence (synchronized at each step):

  STUDENT TEACHER
  Initialize Initialize
 synch 1 AI part 1: learn from answer received and make a new proposal Store correct answer, send to PC and wait for student
synch 2 LEDs on Auto calibrate with LEDs on
synch 3 LEDs off Auto calibrate with LEDs off
synch 4 Display the selected proposal using the LEDs Observe sequence using the LDRs, send to PC, calculate percentage correct and send this to the PC
synch 5 Receive percentage correct. AI part 2: process received answer and add data to brain. Send percentage correct to the student.


This is the student source. It needs to be loaded into the pic with the LEDs.

-- jal 4.55
include JRTL
include f877_20
include jlib
include usart19200
include seriali1200
include seriali
include random3

var byte mydata ,correctCounter, FirstRun, UitTabel, keuze1, keuze2, 
         keuze3, keuze4, t
var byte answer, selectie, temp, NewValue

serial_setup  
                 
-- define the pins
pin_b1_direction = output
pin_b2_direction = output
pin_b3_direction = output
pin_b4_direction = output
pin_b5_direction = output
var bit LED1 is pin_b5
var bit LED2 is pin_b4
var bit LED3 is pin_b3
var bit LED4 is pin_b2
var bit LEDYELLOW is pin_b1

-- array type function to store the brain content in array (x,y)
function MemoryPut(byte in x, byte in y, byte in answer) return byte is
  -- max x = 5 (number of lines)
  -- max y = 6 where 1       serial number
  --                 2,3,4,5 solution
  --                 6       fitness
  -- starting position in memory = 1
  eeprom_put( ( x - 1) * 6 + y + 1, answer )
end function

function MemoryGet(byte in x, byte in y) return byte is
  eeprom_get( ( x - 1) * 6 + y + 1, answer )
  return answer
end function

-- function to generate a random number 1,2,3 or 4
function RandomNumber return byte is
  temp = random_byte
  if temp < 64 then answer = 1 end if
  if temp >= 64 & temp < 128 then answer = 2 end if
  if temp >= 128 & temp < 192 then answer = 3 end if
  if temp >= 192 then answer = 4 end if
  return answer
end function

-- procedure to light a LED
procedure LEDaan(byte in x) is
if x == 1 then
  LED1 = high
  delay_1s
  LED1 = low
  delay_100ms
end if
if x == 2 then
  LED2 = high
  delay_1s
  LED2 = low
  delay_100ms
end if
if x == 3 then
  LED3 = high
  delay_1s
  LED3 = low
  delay_100ms
end if
if x == 4 then
  LED4 = high
  delay_1s
  LED4 = low
  delay_100ms
end if
end procedure
-- fill the fitness part of the brain 
-- with zero's and enter the serial numbers
t = 0
for 5 loop
  t = t + 1
  MemoryPut(t,1,t)
  MemoryPut(t,6,0)
end loop

-- give other pic time to start up
delay_1s

-- this is the first run (so the brain is empty)
FirstRun = 1

forever loop

  -- send current position to the PC
  asynch_send("X")
  asynch_send("0")

-- first synch -----
  mydata = "0"
  while mydata != "A" loop
    F877_serial_receive (mydata)
  end loop
  F877_serial_transmit ( "B" ) 
   -- send current position to the PC
  asynch_send("X")
  asynch_send("1") 
  
  -- *************** AI part 1: selection of the solution ****************

  -- indicator to remember whether the selected solution is from the brain or not
  UitTabel = 0
  
  -- see if the correct answer is known and if yes select
  t = 0
  for 5 loop
    t = t + 1
    MemoryGet(t,6)
    if answer == 4 then
      UitTabel = t
      MemoryGet(UitTabel,2)
      keuze1 = answer
      MemoryGet(UitTabel,3)
      keuze2 = answer
      MemoryGet(UitTabel,4)
      keuze3 = answer
      MemoryGet(UitTabel,5)
      keuze4 = answer
    end if
  end loop
  
  -- if correct answer is not known
  if UitTabel == 0 then
    -- make a choice from the brain (90%)or make up an
    -- answer on the spot (10%)
    selectie = random_byte 
    if selectie > 230 | FirstRun == 1 then
      -- select 4 random numbers in the range 1,2,3,4     
      RandomNumber
      keuze1 = answer   
      RandomNumber
      keuze2 = answer   
      RandomNumber
      keuze3 = answer   
      RandomNumber
      keuze4 = answer   
      FirstRun = 0
    else
      -- random selection from the brain 
      RandomNumber
      UitTabel = answer
      MemoryGet(UitTabel,2)
      keuze1 = answer
      MemoryGet(UitTabel,3)
      keuze2 = answer
      MemoryGet(UitTabel,4)
      keuze3 = answer
      MemoryGet(UitTabel,5)
      keuze4 = answer
                  
      -- make a random mutation (90 % chance)
      selectie = random_byte 
      if selectie < 230  then
        -- reset UitTabel because this is now a new solution
        UitTabel = 0
        RandomNumber
        NewValue = answer
        RandomNumber
        if answer == 1 then keuze1 = NewValue end if
        if answer == 2 then keuze2 = NewValue end if
        if answer == 3 then keuze3 = NewValue end if
        if answer == 4 then keuze4 = NewValue end if
      end if
    end if
  end if
  
  -- second synch -----
  mydata = "0"
  while mydata != "C" loop
    F877_serial_receive (mydata)
  end loop
  F877_serial_transmit ( "D" )

  -- switch yellow led on
  LEDYELLOW = high  

  -- send current position to the PC
  asynch_send("X")
  asynch_send("2") 

  -- calibrate LED's on
  LED1 = high
  LED2 = high
  LED3 = high
  LED4 = high
  
  -- third synch -----
  mydata = "0"
  while mydata != "E" loop
    F877_serial_receive (mydata)
  end loop
  F877_serial_transmit ( "F" )

  -- switch yellow led off
  LEDYELLOW = low

  -- send current position to the PC
  asynch_send("X")
  asynch_send("3") 

  -- calibrate LED's off
  LED1 = low
  LED2 = low
  LED3 = low
  LED4 = low

  -- fourth synch -----
  mydata = "0"
  while mydata != "G" loop
    F877_serial_receive (mydata)
  end loop
  F877_serial_transmit ( "H" )

  -- send current position to the PC
  asynch_send("X")
  asynch_send("4") 
 
 -- display the selected sequence
  LEDaan(keuze1)
  LEDaan(keuze2)
  LEDaan(keuze3)
  LEDaan(keuze4)

  -- fifth synch -----
  mydata = "0"
  while mydata != "I" loop
    F877_serial_receive (mydata)
  end loop
  F877_serial_transmit ( "J" )

  -- send current position to the PC
  asynch_send("X")
  asynch_send("5") 
  
  -- activity signal
  LEDYELLOW = high
  
  -- receive percentage correct from the other PIC
  F877_serial_receive ( correctCounter )

  -- and forward to the PC 
  asynch_send("H")
  asynch_send(correctCounter )
  
  -- yellow led off
  LEDYELLOW = low

  -- go from percentages to range 1-4
  correctCounter = correctCounter / 25

  -- *************** AI part 2: process feedback ****************
    
  -- process CorrectCounter
  if UitTabel == 0 then
    -- if this was a new choice see if a worse one exists in the brain 
    -- table and replace that one
    t = 0
    for 5 loop
      t = t + 1
      MemoryGet(t,6)
      if answer < correctCounter then
        MemoryPut(t,2,keuze1)
        MemoryPut(t,3,keuze2)
        MemoryPut(t,4,keuze3)
        MemoryPut(t,5,keuze4)
        MemoryPut(t,6,correctCounter)
      end if
    end loop
  else
    -- this is an existing selection, so modify the fitness in  the brain
    MemoryPut(UitTabel,6,correctCounter)
  end if

end loop

This is the teacher source, it needs to be loaded into the pic with the LDRs:

-- jal 4.55

include JRTL
include f877_20
include jlib
include usart19200
include seriali1200
include seriali

-- AD converter settings
const PIC_ADC_Nchan            = 5         
const PIC_ADC_NVref            = 0         
const PIC_ADC_Rsource          = 20_000   
const PIC_ADC_high_resolution  = true 

-- AD converter variables
var volatile byte ADCON0      at 0x1F
var volatile bit  GO          at ADCON0 : 2
var volatile byte ADRESH      at 0x1E
var volatile byte ADRESL      at 0x9E
var volatile byte ADCON1      at 0x9F

-- AD library
include pic_adc

-- define variables
var bit loopfix, firstpass, alloff 
var bit SeePinA0, SeePinA1, SeePinA2, SeePinA3
var byte position, x, Correct, correctCounter
var byte RESIST, Dummy, chan, mydata, yelled, counter
var byte threshold0, threshold1, threshold2, threshold3

-- initialize the AD converter
PIC_ADC_init

-- initialize the serial connection to PC
serial_setup        

-- give each pic time to initialize comm buffers
delay_1s           

-- define the pins
pin_a0_direction = input        -- variable resistor       
pin_a1_direction = input        -- variable resistor              
pin_a2_direction = input        -- variable resistor              
pin_a3_direction = input        -- variable resistor              
pin_b1_direction = input        -- switch
pin_b4_direction = output       -- yellow led
var bit LEDYELLOW is pin_b4

-- array type function to store 'answer' in array (x,y)
function PositionPut(byte in x, byte in position) return byte is
-- starting position in memory = 0
eeprom_put(  x + 0 , position )
end function

function PositionGet(byte in x) return byte is
-- starting position in memory = 0
eeprom_get(  x + 0 , position )
return position
end function

-- array type function to store 'answer' in array (x,y)
function CorrectAnswerPut(byte in x, byte in correct) return byte is
-- starting position in memory = 5
eeprom_put(  x + 4 , correct )
end function

function CorrectAnswerGet(byte in x) return byte is
-- starting position in memory = 5
eeprom_get( x + 4 , correct )
return correct
end function

procedure AutoCalibrate is  
  -- pin A0
  PIC_ADC_read (0, Dummy, RESIST)
  asynch_send( "1" )
  asynch_send( Resist )
  asynch_send( "2" )  
  if firstpass == true then
    -- the threshold has no value yet so pick the first one
    threshold0 = resist
  else
    -- from now on take the average
    threshold0 = ( threshold0 / 2) + ( resist / 2 )
  end if
  asynch_send( threshold0)
  delay_100ms

  -- pin A1
  PIC_ADC_read (1, Dummy, RESIST)
  asynch_send( "3" )
  asynch_send( resist )
  asynch_send( "4" )  
  if firstpass == true then
    threshold1 = resist
  else
    threshold1 = ( threshold1 / 2 ) + ( resist / 2 )
  end if
  asynch_send( threshold1)
  delay_100ms

  -- pin A2
  PIC_ADC_read (2, Dummy, RESIST)
  asynch_send( "5" )
  asynch_send( resist )
  asynch_send( "6" )  
  if firstpass == true then
    threshold2 = resist
  else
    threshold2 = ( threshold2 / 2 ) + ( resist / 2 )
  end if
  asynch_send( threshold2)
  delay_100ms

  -- pin A3
  PIC_ADC_read (3, Dummy, RESIST)
  asynch_send( "7" )
  asynch_send( resist )
  asynch_send( "8" )  
  if firstpass == true then
    threshold3 = resist
  else
    threshold3 = ( threshold3 / 2 ) + ( resist / 2 )
  end if
  asynch_send( threshold3)
  delay_100ms
end procedure

procedure MeasureData is 
counter = 1
SeePinA0 = true
SeePinA1 = true
SeePinA2 = true
SeePinA3 = true
alloff = false
while counter < 5 | alloff == false loop 
  alloff = true

  -- pin A0
  PIC_ADC_read (0, Dummy, RESIST)
  -- tell the PC from which pin it will receive data
  asynch_send( "1" )
  if RESIST > threshold0 then
    -- pin is high
    asynch_send( 1 )
    -- obviously not all led's are off, do not exit main loop yet
    alloff = false
    if SeePinA0 then
      PositionPut(counter, 1)
      counter = counter + 1
      -- remember to not count this pin again
      SeePinA0 = false
    end if
  else
    asynch_send( 0 )
    -- pin is low, can count again if needed
    SeePinA0 = true  
  end if

  -- pin A1
  PIC_ADC_read (1, Dummy, RESIST)
  -- tell the PC from which pin it will receive data
  asynch_send( "3" )
  if RESIST > threshold1 then
    asynch_send( 1 )
    alloff = false
    if SeePinA1 then
      PositionPut(counter, 2)
      counter = counter + 1
      SeePinA1 = false
    end if
  else
    asynch_send( 0 )
    -- pin is low, can count again if needed
    SeePinA1 = true  
  end if

  -- pin A2
  PIC_ADC_read (2, Dummy, RESIST)
  asynch_send( "5" )
  if RESIST > threshold2 then
    asynch_send( 1 )
    alloff = false
    if SeePinA2 then
      PositionPut(counter, 3)
      counter = counter + 1
      SeePinA2 = false
    end if
  else
    asynch_send( 0 )
    SeePinA2 = true  
  end if

  -- pin A3
  PIC_ADC_read (3, Dummy, RESIST)
  asynch_send( "7" )
  if RESIST > threshold3 then
    asynch_send( 1 )
    alloff = false
    if SeePinA3 then
      PositionPut(counter, 4)
      counter = counter + 1
      SeePinA3 = false
    end if
  else
    asynch_send( 0 )
    SeePinA3 = true  
  end if
end loop
end procedure

forever loop
  -- send current position to the PC
  asynch_send("X")
  asynch_send("0")

-- first synch -----
  F877_serial_transmit ( "A" ) 
  mydata = "0"
  while mydata != "B" loop
    F877_serial_receive (mydata)
  end loop

  -- send current position to the PC
  asynch_send("X")
  asynch_send("1") 

  -- store the correct answer ( 1 - 3 - 2 - 4 )
  CorrectAnswerPut(1,1)
  CorrectAnswerPut(2,3)
  CorrectAnswerPut(3,2)
  CorrectAnswerPut(4,4)
  
  -- and send to PC
  CorrectAnswerGet(1)
  asynch_send("I")
  asynch_send(correct)  
  CorrectAnswerGet(2)
  asynch_send("J")
  asynch_send(correct)  
  CorrectAnswerGet(3)
  asynch_send("K")
  asynch_send(correct)  
  CorrectAnswerGet(4)
  asynch_send("L")
  asynch_send(correct) 
 
  -- second synch -----
  -- calibrate with LED's on
  F877_serial_transmit ( "C" ) 
  mydata = "0"
  while mydata != "D" loop
    F877_serial_receive (mydata)
  end loop
   
  -- switch yellow led on
  LEDYELLOW = high 
  asynch_send("9")
  asynch_send("1") 

  -- send current position to the PC
  asynch_send("X")
  asynch_send("2")

  -- wait a bit to make sure LED's are actually on
  delay_100ms

  -- calibrate
  firstpass = true
  for 2 loop
    AutoCalibrate
    firstpass = false
    delay_10ms
  end loop
  
  -- third synch -----
  -- calibrate with LED's off
  F877_serial_transmit ( "E" ) 
  mydata = "0"
  while mydata != "F" loop
    F877_serial_receive (mydata)
  end loop
  
  -- switch yellow led off
  LEDYELLOW = low
  asynch_send("9")
  asynch_send("0") 

  -- send current position to the PC
  asynch_send("X")
  asynch_send("3")  

  -- wait a bit to make sure LED's are actually on
  delay_100ms

  -- calibrate
  for 2 loop
    AutoCalibrate
    delay_10ms
  end loop
  
  -- fourth synch -----
  -- observe the sequence
  F877_serial_transmit ( "G" ) 
  mydata = "0"
  while mydata != "H" loop
    F877_serial_receive (mydata)
  end loop

  -- send current position to the PC
  asynch_send("X")
  asynch_send("4") 
  
  -- reading student data
  MeasureData

  -- and send result (sequence) to the PC
  -- read arry and send to PC
  PositionGet(1)
  asynch_send("C")
  asynch_send(position)  
  PositionGet(2)
  asynch_send("D")
  asynch_send(position)  
  PositionGet(3)
  asynch_send("E")
  asynch_send(position)  
  PositionGet(4)
  asynch_send("F")
  asynch_send(position)  

  -- check for correctness
  CorrectCounter = 0
  counter = 1
  while counter < 5 loop
    PositionGet(counter)
    CorrectAnswerGet(counter) 
    if position == correct then
      correctCounter = correctCounter + 1
    end if
    counter = counter + 1
  end loop

  -- send percentage correct to the PC
  asynch_send("H")
  asynch_send(correctCounter * 25) 
  
  -- fifth synch -----
  F877_serial_transmit ( "I" ) 
  mydata = "0"
  while mydata != "J" loop
    F877_serial_receive (mydata)
  end loop

  -- send current position to the PC
  asynch_send("X")
  asynch_send("5") 
  
  -- send percentage correct to the other PIC
  F877_serial_transmit ( correctCounter * 25)
  
end loop

The include file seriali1200.jal contains the following:

-- settings required for seriali to work
const asynch_baudrate = 1200
const asynch_polarity = active_high
const asynch_parity   = parity_none
const asynch_stopbits = 2

-- define input and output pins
var volatile bit asynch_in_pin        is pin_b6
var volatile bit asynch_in_direction  is pin_b6_direction
var volatile bit asynch_out_pin       is pin_b7
var volatile bit asynch_out_direction is pin_b7_direction

The include file usart19200.jal contains the following:

-- --------------------------------------------------------------------
--
-- file         : usart19200.jal
-- author       : Javier Martinez, put in a lib by Bert van Dam, added
--                poll routine 
-- date         : 13 june 2004
-- purpose      : setup file for usart for 19200 baud
--                which is pin c6/c7 (25 and 26 on a 16F877)
-- usage        : include this file, call serial_setup to initialise
--
-- --------------------------------------------------------------------

-- setting for USART use
--        receive is RC7   (pin 26)
--        send is RC6      (pin 25)
var volatile bit  f877_BRGH     at f877_TXSTA : 2
var volatile bit  f877_TXEN     at f877_TXSTA : 5
var volatile bit  f877_CREN     at f877_RCSTA : 4
var volatile bit  f877_SPEN     at f877_RCSTA : 7
var volatile bit  f877_TXIF     at f877_PIR1 : 4
var volatile bit  f877_RCIF     at f877_PIR1 : 5

-- variable to see if data is received
var bit polltrue

Procedure serial_setup is begin
  -- general setup procedure 19200,8,n,1 No handshaking
  Bank_1
  f877_SPBRG = 64
  f877_BRGH = high
  f877_TXEN = High
  Bank_0
  f877_CREN = high
  f877_SPEN = high
end procedure

Procedure F877_serial_receive ( byte out data ) is begin
  -- wait for incoming data and receive
  Bank_0
  while ! f877_RCIF loop
  end loop
  file_get ( 0x1A , data )
end procedure

Procedure F877_serial_transmit ( byte in data ) is begin
  -- transmit data
  Bank_0
  while ! f877_TXIF loop
  end loop
  file_put ( 0x19 , data )
end procedure

Procedure F877_serial_poll ( byte out data ) is begin
  -- see if there's any data to receive, if yes receive the
  -- data and set the polltrue flag to true
  Bank_0
  polltrue = false
  if f877_RCIF then
    file_get ( 0x1A , data )
    polltrue = true
  end if
end procedure

A lot of data is send to the PC by each of the pics. Normally only the teacher is connected to the PC, the student messages to the PC are for debugging only. This is the code list of all messages:

Code Contents
1 pin 2 (a0), measurement or 1/0
2 threshold a0, division between high and low
3 pin 3 (a1), measurement or 1/0
4 Threshold a1, division between high and low
5 pin 4 (a2), measurement or 1/0
6 threshold a2, division between high and low
7 pin 5 (a3), measurement or 1/0
8 threshold a3, division between high and low
9 pin 37 (b4) or pin 34 (b1) on student pic
C first LDR, measurement
D second LDR, measurement
E third LDR, measurement
F fourth LDR, measurement
H fitness, in percentage
I correct 1st step in sequence
J correct 2nd step in sequence
K correct 3rd step in sequence
L correct 4th step in sequence
X program step in progress

Submitted: 06/02/2005

Article content copyright © Bert van Dam, 2005.
 Article Toolbar
Print
BibTeX entry

Search

Latest News
- Generation5 10-year Anniversary (03/09/2008)
- New Generation5 Design! (09/04/2007)
- Happy New Year 2007 (02/01/2007)
- Where has Generation5 Gone?! (04/11/2005)
- NeuroEvolving Robotic Operatives (NERO) (25/06/2005)

What's New?
- Back-propagation using the Generation5 JDK (07/04/2008)
- Hough Transforms (02/01/2008)
- Kohonen-based Image Analysis using the Generation5 JDK (11/12/2007)
- Modelling Bacterium using the JDK (19/03/2007)
- Modelling Bacterium using the JDK (19/03/2007)


All content copyright © 1998-2007, Generation5 unless otherwise noted.
- Privacy Policy - Legal - Terms of Use -