Monday 26 November 2018

How do you specify a range of random numbers?

The Common Lisp function RANDOM takes two arguments: a limit and a random state. The first argument tells to the function that the generated random number could be one in the range of 0 <= n < limit, for example:

CL-USER> (random 1000)
860

or:

CL-USER> (random 1.0)
0.2709539

from these examples we clearly understand that limit could be an integer or float number. The second parameter passed to RANDOM is the random state, according to hyperspec http://clhs.lisp.se/Body/t_rnd_st.htm#random-state) is an object which holds informations used by the random number generator inside the computer which are different from implementation to implementation.
 

Wednesday 4 May 2016

Know Your Tables?


The RANDOM function has hundreds of uses in programming. Suppose, for example, you wanted a program to teach your eight-year-old son or brother his 9-times table. You could set it up like this:

(defun table-guess ()
   "Let the boy guesses the table."
   (let ((a 0))
     (format *terminal-io* "What is 1 times 9? ")
     (clear-input *terminal-io*)
     (setq a (read *terminal-io*)
     (when (= a 9)
       (format *terminal-io* "Correct~%"))
     (format *terminal-io* "What is 2 times 9? ")
     (clear-input *terminal-io*)
     (setq a (read *terminal-io*)
     (when (= a 18)
       (format *terminal-io* "Correct~%"))
    ...



...and so on. But this would give you a very long program - without even solving the problem of how the computer responds if one of this answer is wrong!
    Use the RANDOM function, however, and you can produce a much more compact program that will not only ask all the right questions, but ask them in random order a much better way of teaching, as well as of programming.
    Particularly when you are learning programming, it is always best to work out of the 'core' of a program before adding the frills. So first try these forms:


(let ((n (1+ (random 12)))
  (a 0))
  (format *terminal-io* "What is ~a times 9? " n)
  (clear-input *terminal-io*)
  (setq a (read *terminal-io*))
  (when (= a (* n 9))
    (format *terminal-io* "Correct~%")))

this form is using RANDOM function in the same way as in the guessing game. The LET macro first set up two variables: one for the random number the computer selects and the other for user guessing. Then, with the same LET form, you tell the computer to pick a number - any integer number - between 1 and 12. (The 1+ function is necessary because the random numbers starts at 0 - a number not wanted for this job).
    In the first FORMAT form you ask the player to multiply by 9 whichever number the computer has chosen this time. The SETQ special form actually take the console input and stores in the a variable. The WHEN macro warns the computer to multiply this number by 9, compare this with the player's answer and - if the latter is correct - print "Correct".
    Execute this form and you will find that it works - once. You could make it continuous by modifying it as follows:

(loop named guess-table do
  (let ((n (1+ (random 12)))
        (a 0))
    (format *terminal-io* "What is ~a times 9? " n)
    (clear-input *terminal-io*)
    (setq a (read *terminal-io*))
    (when (= a (* n 9))(
      (format *terminal-io* "Correct~%"))))

...but why not do the job properly, as here:


(defun guess-tables ()
  (let ((player-name nil)
        (n nil)
        (a nil))
    (format *terminal-io* "Hello. What is your name? ")
    (clear-input *terminal-io*)
    (setq player-name (read *terminal-io*))
    (format *terminal-io* "Hello, ~a, I have some questions for you~%" player-name)
    (sleep 2)
    (loop named game-loop do
      (setq n (1+ (random 12)))
      (loop named wrong-answer-loop do
          (format *terminal-io* "What is ~a times 9? " n)
          (clear-input *terminal-io*)
          (setq a (read *terminal-io*))
        if (= (* n 9) a) do
          (format *terminal-io* "Well done, ~a, here is the next one~%" player-name)
          (return-from wrong-answer-loop)
        else do
          (format *terminal-io* "Sorry, please try again~%"))
        (sleep 1))))

the SLEEP function simply waste time, by making the computer 'count up to' a certain number before springing the next question on your unsuspecting infant. (How it does this is in Common Lisp Programming 2).
    From the viewpoint of your eight-year-old, this function has one terrible disadvantage: it goes on and on without stopping. You can release him from this misery, like this: push CTRL, then C and when the interpreter drops in the debugger press Q.
    From your viewpoint, on the oder hand, the program has a bonus feature: simply by changing the 9s in the function to 5s, 6s, 7s or whatever, you can test him on all his tables.
    And because the computer does all the computations, you do not need to know any of the answers yourself!
    Anyway to avoid the program to be changed for every table, let render the GUESS-TABLES function more general:

(defun guess-tables (base-number)
  (let ((player-name nil)
        (n nil)
        (a nil))
    (format *terminal-io* "Hello. What is your name? ")
    (clear-input *terminal-io*)
    (setq player-name (read *terminal-io*))
    (format *terminal-io* "Hello, ~a, I have some questions for you~%" player-name)
    (sleep 2)
    (loop named game-loop do
        (setq n (1+ (random 12)))
        (loop named wrong-answer-loop do
           (format *terminal-io* "What is ~a times ~a? " n base-number)
           (clear-input *terminal-io*)
           (setq a (read *terminal-io*))
          if (= (* n base-number) a) do
           (format *terminal-io* "Well done, ~a, here is the next one~%" player-name)
           (return-from wrong-answer-loop)
          else do
           (format *terminal-io* "Sorry, please try again~%"))
        (sleep 1))))

Now would be fine if the computer could track down the number of guesses vs. the player's right answers:


(defun guess-tables (base-number)
  (let ((player-name nil)
        (correct-guesses 0)
        (n nil)
        (a nil))
    (format *terminal-io*
            "Hello. What is your name? ")
    (clear-input *terminal-io*)
    (setq player-name (read *terminal-io*))
    (format *terminal-io*  
            "Hello, ~a, I have some questions for you~%" 
            player-name)
    (sleep 2)
    (loop named game-loop
          for guess-count from
          do
            (format *terminal-io*  
                    "~a correct guesses on ~a. Question #~a "
                    correct-guesses 
                    (1- guess-count) 
                    guess-count)
        (setq n (1+ (random 12)))
        (loop named wrong-answer-loop 
            do
                (format *terminal-io* 
                        "What is ~a times ~a? " 
                        n
                        base-number)
                (clear-input *terminal-io*)
                (setq a (read *terminal-io*))
            if (= (* n base-number) a)  
            do
                (format *terminal-io* 
                        "Well done, ~a, here is the next one~%"
                        player-name)
                (incf correct-guesses)
                (return-from wrong-answer-loop)
            else
            do
                (format *terminal-io*
                        "Sorry, please try again~%"))
           (sleep 1))))


(guess-tables 2)

As you can see to advance towards the next question, the player must enter the correct answer, this is not the case. In fact if the player needs to end the game he/she has to enter CTRL+C and the Q keys. Let's modify again to prevent this:


(defun guess-tables (base-number)
  (let ((player-name nil)
        (correct-guesses 0)
        (n nil)
        (a nil))
    (format *terminal-io* 
            "Hello. What is your name? ")
    (clear-input *terminal-io*)
    (setq player-name (read *terminal-io*))
    (format *terminal-io*  
            "Hello, ~a, I have some questions for you~%"
            player-name)
    (sleep 2)
    (loop 
        named game-loop
        for guess-count from 1
        do
            (format *terminal-io*  
                    "~a correct guesses on ~a. Question #~a "
                    correct-guesses
                    (1- guess-count)
                    guess-count)
            (setq n (1+ (random 12)))
            (format *terminal-io* 
                    "What is ~a times ~a? "
                    n
                    base-number)
            (clear-input *terminal-io*)
            (setq a (read *terminal-io*))
            (if (= (* n base-number) a)
                (progn
                    (format *terminal-io*
                            "Well done, ~a, here is the next one~%"
                            player-name)
                    (incf correct-guesses))
                (format *terminal-io*
                        "Sorry, wrong answer.~%"))
            (sleep 1)
        unless (yes-or-no-p "Another game? ")
        do
            (format *terminal-io*
                    "Bye ~a, you scored ~a on ~a correct answers.~%"
                    player-name
                    correct-guesses
                    guess-count)
            (return-from game-loop))))

(guess-tables 3)

Tuesday 31 March 2015

What if Village People guys were CL programmers???

-Login
-CL hotline hyperspec
-What's your credit card number?
-69667113
-Your ip address?
-7.51.61.77
-What's your preferred programming language?
-I just wanna code in a very hot way
-We'll ssh you back

Sexp over the net
Sexp over the net
Sexp over the net
Sexp over the net

Well I just want to code
Lately I smile with emacs mode
Lately dsl is never down
lately I never frown
At home or in the car
don't matter where you are
Don't wanna be a weasel
you just pick up CL REPL

Sexp over the net
You know I like it
Sexp over the net
You know I code it
Sexp over the net
Come on and give it to me baby
Sexp over the net

When I want to write a database I don't have to go SQL
I don't need to read books if I'm feeling lazy
I can lie there in my bed writing code in my REPL
I just touch my keys and I go crazy

Sexp over the net
In the morning
Sexp over the net
In the afternoon
Sexp over the net
Sometimes late in the evening
Sexp over the net

This is the part I hate
why do they make you use Basic?
Here's where the rage rise
Enough to cross my eyes

They can be short or long

they can be with numbers or strings.
I don't care not at all
long as they go in the net

Sexp over the net
It's so fulfilling
Sexp over the net
They're always willing
Sexp over the net
Don't break connection baby
Sexp over the net.

-M-x slime
-Connected! Hacks and glory await!
-M-x slime
-Connected. Take this REPL, brother, and may it serve you well.
-M-x slime
-Connected. May the source be with you!

Sexp over the net
My.... is my....
Sexp over the net
my eyes
Sexp over the net
I need a REPL

It's coding that you need
satisfaction guaranteed
It won't cost that much for you to start programming lisp
It's a very small amount on your time account
Come on let your fingers do the walking

Sexp over the net
Sexp over the net
Sexp over the net
Sexp over the net
Sexp over the net
They're always willing
Sexp over the net
It's so fulfilling
Sexp over the net
Come on and give it to me baby
Sexp over the net

If you are feelin' a geek and after all who's not?
Right now I've got a cure to help your feature
All that you need's a slime and just a little time
A pay dsl on the street can help you beat the heat

Sexp over the net
You know I like it

Wednesday 14 January 2015

Think of a number... Any number.


Learning to program it's not an easy task: there are several aspects to consider, for example which language and system. One could even start learn programming for the embedded world directly in assembly or choose to master WEB development with javascript. Anyway we think that the learning process is more efficient when it's carried out with practical examples so let's start!

 

 Guessing the number.

The easiest of all computer games to program is the one in which the computer choose randomly from a set of integer numbers and the user tries to guess it. To start programming without installing anything on the computer you can use this site and follow its instruction to setup an user account. After you logged in you face the REPL with input point represented by a "?"

 

 The random function.

All Common Lisp implementations have a random number generation function to allow people invent such games and others. As described in the hyperspec the function random is:
(random limit &optional random-state)
It returns a number equal to zero or less than the limit parameter which could be integer or float. According to the book "Common Lisp the Language, 2nd Edition" (pag. 391) the random-state is an object used to maintain the state of the pseudo-random-number generator and is altered as a side effect of the random operation. Its default value is *random-state*. The random-state type is implementation-dependent; it means that it is possible to print out an object of this type and then read back but this may or may not work correctly in another implementation. Let's go on and enter from REPL:
 
(defparameter *generator-random-state* 
              (make-random-state t))   
(defparameter *minimum-guess-number*
              "The smallest integer to choose from.")  (defparameter *maximum-guess-number* 10 
              "The greatest integer to choose from.")      
 
(defun generate-integer (minimum-value maximum-value)     
    "Generate a random number inside a span."
    (+ minimum-value  
      (random (1+ (- maximum-value minimum-value)) 
              *generator-random-state*)))
 
So what have we done here is create a new function named GENERATE-INTEGER along with the special variable *generator-random-state*. Useful programs are often made of functions, called in a particular sequence, that accept zero, one or more parameters and returns single or more values. There's no a privileged function, like in other languages, where to start a program, since code execution is made by calling functions from REPL or from other functions. We entered another kind of form (defun ...) which is a "special form" the evaluation of this won't execute code in the sense of the function itself, but instruct the interpreter how to form our function. If we enter from REPL:
 
(loop  
    repeat 10
    do     (format *terminal-io* 
                "~a "  
                (generate-integer 1 6)))

We obtain for example:
6 4 1 6 3 4 3 3 5 4

now let's move toward a proper user interface for a game and enter two more functions:

(defun guess-an-integer (number-of-attempts) 
"Ask for the secret number for a limited number of times."
(let ((secret-number (generate-integer *minimum-guess-number*
*maximum-guess-number*)))
        (unless (loop 
                    named try-loop 
                    for i from 1 upto number-of-attempts
                    do
                        (format *terminal-io* 
                               "try number ~a, insert a number from ~a to ~a: "
                          i
                          *minimum-guess-number*  
                          *maximum-guess-number*)                                         (finish-output *query-io*) 
                        (let ((guess (read *query-io*)))                                      (when (= guess secret-number) 
                                (format *terminal-io* 
                                        "Bingo! You did it in ~a attempts.~%" 
                                        i)
                                (return-from try-loop t))))
                            (format *terminal-io*
                                    "I'm sorry you loose!~%")))) 
 
  and:
(defun play-repeatedly ()
  "Play the guessing game repeatedly until user type exit." 
  (let ((number-of-attempts nil)) 
     (loop named guess-game-loop do
      (format *terminal-io* "How many attempts would you like to try? (type 'exit' to exit): ")
     (finish-output *query-io*)
     (setq number-of-attempts (read *query-io*)) 
     (cond
        ((and (symbolp number-of-attempts)
         (string-equal 'exit number-of-attempts)) 
         (return-from guess-game-loop))
       ((typep number-of-attempts 'integer) 
         (if (< number-of-attempts 1)
          (format *standard-output* "Only positive number or zero to exit!~%")
           (guess-an-integer number-of-attempts)))))))
 Now the important thing to understand is that in Common Lisp programs are made of functions: we defined three of them for our guessing game, GENERATE-INTEGER, GUESS-AN-INTEGER and PLAY-REPEATEDLY. The latter must be evaluated to actually play the game.

Using variables.

In the code above we used variable to hold particular values useful in the program for particular computations. However there is no need to declare the type of object that a variable will hold. The object/value carries information to perform type check during runtime. Assigning a variable a new value changes what object the variable refers to but has no effect on the previously referenced object/values. If a variable refers to a mutable object, that reference could be used to modify the object itself, then this modification will be visible to any code that has a reference to the same mutable object. Practically a variable name refers to a place in memory that actually holds the value/object, when the reference between the two is created it is called a "binding", through it it's possible to operate on a mutable object or value. In our case multiple bindings are created during runtime, for example in the call of GENERATE-INTEGER where parameters a and b are binded to 1 and 6 respectively. In the let special form in PLAY-REPEATEDLY function, the symbol number-of-attempts is binded to nil.

The (read) special form.

The program will ask the player how many attempts he has left to guess the secret number. Having generated this value, the next step is to instruct the computer to accept the player guess. To enter the number of attempts and the attempt itself we used the special form (read). For now you could think at read as a command to make the computer waits until some data is provided by external means, in this case the keyboard. The value entered is then placed in the memory referred by the symbol guess, due to the let form in GUESS-AN-INTEGER. The reader must understand that there are a lot of way to enter a number from outside a program just using the read special form, but enter data from the keyboard is the fastest and most natural way to interact with the user, which is now a player, that runs the program. Generally speaking the read form could take data from streams and perform several interesting operations on them as a plus. For now just play and have fun:

(play-repeatedly)
 

Friday 15 November 2013

Let's dance!

S-B-C-L!

Young geek, there's no need to feel down.
I said, young geek, pick yourself off the ground.
I said, young geek, 'cause you're in a new old language
There's no need to be unhappy.

Young geek, there's a language you can use.
I said, young geek, when you're short on your code.
You can use that, and I'm sure you will find
Many ways to have a good time.

It's fun to program with the s-b-c-l.
It's fun to program with the s-b-c-l.

It has everything for you geek to code,
You can hang out with the emacs mode ...

It's fun to program with the s-b-c-l.
It's fun to program with the s-b-c-l.

You can get working code, you can have a program,
You can do whatever you feel ...

Young geek, are you listening to me?
I said, young geek, what do you want to be?
I said, young geek, you can make real your dreams.
But you got to know this one thing!

No geek does it all by himself.
I said, young geek, put your pride on the shelf,
And just program, with the s.b.c.l.
I'm sure it can help you today.

It's fun to program with the s-b-c-l.
It's fun to program with the s-b-c-l.

It has everything for you geek to enjoy,
You can hang out with emacs mode ...

It's fun to program with the s-b-c-l.
It's fun to program with the s-b-c-l.

You can get woking code, you can have a program,
You can do whatever you feel ...

Young geek, I was once in your shoes.
I said, I was down and out with the bugs.
I felt no geek cared if I were alive.
I felt the whole hard disk was so tight ...

That's when someone came up to me,
And said, young geek, take a walk up the GNU.
There's a program there called the s.b.c.l.
It can start you back on your way.

It's fun to program with the s-b-c-l.
It's fun to program with the s-b-c-l.

It has everything for you geek to enjoy,
You can hang out with emacs mode ...

S-b-c-l ... you'll find it in the s-b-c-l.

Young geek, young geek, there's no need to feel down.
Young geek, young geek, get yourself off the bugs.

S-b-c-l ... you'll find it in the s-b-c-l.

Young geek, young geek, there's no need to feel down.
Young geek, young geek, get yourself off the bugs.

S-b-c-l ... just use the s-b-c-l.

Young geek, young geek, are you listening to me?
Young geek, young geek, what do you wanna be?

Fernando

Can you hear the beeps Fernando?
I remember long ago another language not like this
In the slime session Fernando
You were humming to yourself and softly strumming your keyboard
I could hear the distant console beep coming from above

They were closer now Fernando
Every keystroke seemed to last eternity
I was so afraid Fernando
We were young and full of bugs and none of us prepared to code
And I'm not ashamed to say
The bad c/c++ code almost made me cry

There was repl in emacs that night
The parens were green, Fernando
They were blinking there for you and me
For programming, Fernando
Though I never thought we could code
There's no brace left
If I hade to do the same again
I would, my geek, Fernando
If I hade to do the same again
I would, my geek, Fernando

Now we're old and geek Fernando
And since many programs I have done for live
Can you hear the beeps Fernando?
Do you still recall what the Meta dot means?
I can see it in your eyes
How proud you were to write macros

That was something in the air that night
The parens were higlights, Fernando
They were blinking over here and over there
For programming, Fernando

Tuesday 11 September 2012

Radio kills the video star.

A little project involving USB.

a simple Common Lisp program to send data from PC to an homemade board based on pic18lf2455 via USB hid interface.The friend Pascal. J. Bourguignon provided the with-open-usb macro.

This simple project starts from the need to provide a way to send and receive data over a custom board based on pic18lf2455. The application uses the microchip USB stack firmware for pic18 microcontrollers series and could take a bunch of commands to perform different operations such like: read digital signals timing and configure a digital radio chip (CC110L from TI). The main Lisp application has got three files:

  • usb.asd;
  • usb.lisp;
  • package.lisp;
  • README.txt

For this project I used Quicklisp 2012081400, Quickproject, SBCL 1.0.57, Emacs 23 and Slime from Wheezy distro. The Lisp program could:

  • Lit/unlit 3 different LEDs on board;
  • Capture digital RF signals timings from main antenna;
  • Control digital radio CC110L micro from TI;
  • handle USB communication;
  • read a two keys pad.

Here a tipical session on the SBCL REPL.


*slime-repl sbcl*
; SLIME 2012-05-25
CL-USER> (ql:quickload "usb")
To load "usb":
  Load 1 ASDF system:
    usb
; Loading "usb"
............
("usb")
CL-USER> (usb::send-command usb::*ccp1-on-command* :listen 4 :debug t)
Found device Vendor ID: 0x04D8, Product ID: 0x003C
Device opened.
Configuration 1 set.
Interface 0 claimed.
AltInterface 0 set.

Sending:
0x77 0x02 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

Receiving:
0x77 0x3C 0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

0x77 0x3C 0x01 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

0x77 0x3C 0x02 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

0x77 0x3C 0x03 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

(#8m( 119   60    0    0  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255)
 #8m( 119   60    1    0  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255)
 #8m( 119   60    2    0  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255)
 #8m( 119   60    3    0  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255))
CL-USER> 
-->

in this session the CCP1 is activated via a specific command, the program then fetches three timings packets (64 bytes each) over the USB, the first packet is the response to the command. In this case there are all timeouts (data = 0xffff). In this other session the program do the same with a 30 MHz RF signal captured from the antenna.


*slime-repl sbcl*
CL-USER> (usb::send-command usb::*ccp1-on-command* :listen 4 :debug t)
Found device Vendor ID: 0x04D8, Product ID: 0x003C
Device opened.
Configuration 1 set.
Interface 0 claimed.
AltInterface 0 set.

Sending:
0x77 0x02 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 

Receiving:
0x77 0x02 0x01 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 

0x77 0x3C 0x00 0x00 0x82 0x03 0x03 0x00 0x07 0x00 0x28 0x00 0x48 0x00 0x3E 0x00 
0x34 0x00 0x2B 0x00 0x28 0x00 0xC0 0x01 0x04 0x00 0x0C 0x00 0x39 0x00 0x3C 0x00 
0x36 0x00 0x2E 0x00 0x27 0x00 0x26 0x00 0x22 0x00 0x22 0x00 0x20 0x00 0x1F 0x00 
0x1D 0x00 0x1D 0x00 0x1D 0x00 0x1D 0x00 0x81 0x03 0x02 0x00 0x05 0x00 0x21 0x00 

0x77 0x3C 0x01 0x00 0x4D 0x00 0x3A 0x00 0x31 0x00 0xD6 0x01 0x02 0x00 0x06 0x00 
0x1E 0x00 0x8E 0x00 0x43 0x00 0x2C 0x00 0x26 0x00 0x26 0x00 0x24 0x00 0x1F 0x00 
0x20 0x00 0x1E 0x00 0x1D 0x00 0x1D 0x00 0x1D 0x00 0x1D 0x00 0x72 0x03 0x04 0x00 
0x0A 0x00 0x43 0x00 0x4C 0x00 0x39 0x00 0x2F 0x00 0x2A 0x00 0xCF 0x01 0x02 0x00 

0x77 0x3C 0x02 0x00 0x10 0x00 0x20 0x00 0x2D 0x00 0x33 0x00 0x3E 0x00 0x4B 0x00 
0xBA 0x03 0x03 0x00 0x0A 0x00 0x23 0x00 0x39 0x00 0x4B 0x00 0x62 0x00 0x11 0x02 
0x02 0x00 0x06 0x00 0x1B 0x00 0x47 0x00 0x61 0x00 0x52 0x00 0x3C 0x00 0x33 0x00 
0x15 0x00 0x26 0x00 0x24 0x00 0x22 0x00 0x1F 0x00 0x1E 0x00 0x85 0x03 0x02 0x00 

(#8m( 119    2    1    0  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255  255)
 #8m( 119   60    0    0  130    3    3    0    7    0   40    0   72    0   62    0   52    0   43    0   40    0  192    1    4    0   12    0   57    0   60    0   54    0   46    0   39    0   38    0   34    0   34    0   32    0   31    0   29    0   29    0   29    0   29    0  129    3    2    0    5    0   33    0)
 #8m( 119   60    1    0   77    0   58    0   49    0  214    1    2    0    6    0   30    0  142    0   67    0   44    0   38    0   38    0   36    0   31    0   32    0   30    0   29    0   29    0   29    0   29    0  114    3    4    0   10    0   67    0   76    0   57    0   47    0   42    0  207    1    2    0)
 #8m( 119   60    2    0   16    0   32    0   45    0   51    0   62    0   75    0  186    3    3    0   10    0   35    0   57    0   75    0   98    0   17    2    2    0    6    0   27    0   71    0   97    0   82    0   60    0   51    0   21    0   38    0   36    0   34    0   31    0   30    0  133    3    2    0))
CL-USER> (usb::send-command usb::*ccp1-off-command* :listen 1 :debug t)
Found device Vendor ID: 0x04D8, Product ID: 0x003C
Device opened.
Configuration 1 set.
Interface 0 claimed.
AltInterface 0 set.

Sending:
0x77 0x02 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 

Receiving:
0x77 0x02 0x01 0x00 0x1A 0x00 0x4A 0x00 0x73 0x00 0xB7 0x00 0x74 0x03 0x09 0x00 
0x39 0x00 0x9B 0x00 0x70 0x02 0x02 0x00 0x08 0x00 0x60 0x00 0xCC 0x00 0x6D 0x00 
0x4A 0x00 0x35 0x00 0x2F 0x00 0x2A 0x00 0x24 0x00 0x8A 0x03 0x02 0x00 0x04 0x00 
0x18 0x00 0x6F 0x00 0x59 0x00 0x42 0x00 0xEF 0x01 0x04 0x00 0x05 0x00 0x0D 0x00 

(#8m( 119    2    1    0   26    0   74    0  115    0  183    0  116    3    9    0   57    0  155    0  112    2    2    0    8    0   96    0  204    0  109    0   74    0   53    0   47    0   42    0   36    0  138    3    2    0    4    0   24    0  111    0   89    0   66    0  239    1    4    0    5    0   13    0))
CL-USER> 
-->

Program could redirect output into a file and perform never ending sampling.

The RSS Feed