Raspberry, bottom, and camera, top.https://en.wikipedia.org/wiki/Raspberry_Pi is a $35 computer; a camera adds another $25. Add in a power supply and an internet connection and it is remotely accessible. How can JMP access it?
In this example, plink (part of the PuTTY suite), and RunProgram (part of JMP), connect JMP to the Linux command line interface in the Raspberry Pi. JMP sends the raspistill command, with parameters that tell the Raspberry Pi how to take the picture and where to put it, then JMP closes the connection and displays the picture from its location on the network.
See https://community.jmp.com/t5/Uncharted/Can-JSL-talk-to-Linux/ba-p/33689 for similar ideas using non-Raspberry Linux machines. One of the issues is avoiding password prompts by creating a public/private key pair; I used puttygen (PuTTY suite) to make my public/private keypair (not shown), and I made my JSL a lot simpler by saving a profile in putty named camera; the profile has the connection information:
PuTTY dialog high lighting load/save sessions and Auth
PuTTY dialog showing private key in Auth
Login using the public/private key
Now the profile is also available to plink as camera. So, here's some JSL to login:
rp = RunProgram(
executable( "plink" ), // plink is part of the PuTTY toolset, a bit like SSH
options( "camerapi" ), // this is a saved session in PuTTY
ReadFunction(
Function( {this},
While( this << canread,
Write( this << read ); // stream output to JMP log window
Wait( .01 );
)
)
)
);
This JSL leaves rp holding a RunProgram object that is running in the background, waiting for the shell program on the Raspberry to produce some output...which it copies to the JMP log window:
The first yellow is a message from JMP; the last yellow is a prompt from the Raspberry
The white log window contains the same login results as the black shell window. The ESC stuff color-codes the output so I get a cyan prompt. And the RunProgram object is still waiting to pass some commands to the Raspberry Pi. Construct a command and send it:
// filename builds a path known to the linux (raspberry pi) computer; it is
// actually a nfs mount from yet another computer. This filename is where the
// picture will be stored. The windows computer running JMP can access the
// NFS mount via the H: drive, which is being supplied through VirtualBox.
filename = "capture/picNoOptions.jpg";
// raspistill is a raspberry pi-specific linux command to take a picture
// using the camera attached to the raspberry pi. Because this is a
// command line interface the command must end with a newline, as if
// it was typed at the keyboard and ENTER was pressed.
command = "raspistill --timeout 1000 --nopreview --output " ||"/mnt/nfsc/upscale/"|| filename;
rp << Write( command || "\!n" ); // send the raspistill command, via the linux command line
This produces some more output in the log window:
The command is in yellow, it runs silently, and prompts for another command
At this point the RunProgram connection can be closed; sending the exit command to the running shell is the best way to disconnect cleanly:
// for RunProgram to end cleanly, the shell it is running must terminate
rp << Write( "exit\!n" ); // end the Linux shell session
Again, there is a bit of log window output:
The shell is now closed
The remainder of the JSL will wait, as needed, then clean up:
// every thing above happened very quickly, but the raspistill and exit
// commands have not finished yet. ask the rp object, over and over, if
// the pipe of data from the shell back to JSL has been closed yet. Until
// the ReadEOF happens, RunProgram will not terminate nicely.
While( !(rp << isReadEOF), write("."); Wait( .25 ) ); // wait patiently while shell output goes to log
If( !(rp << canread) & !(rp << canwrite) & rp << isReadEOF,
rp = 0; // this will really make RunProgram go away
Write( "\!nDone" );
,
// possibly need to restart JMP, and possibly need to restart raspberry
Write( "\!nFailed to release rp" )
);
Because I waited for the output already, it just says "Done". You might need to add wait(0.1) before the if( canread/canwrite/isReadEOF ) test to get Done every time.
Now grab the picture from the network and show it:
img=newimage("h:/"||filename);
img<<scale(.125);
newwindow("test",img);
1/8 actual size, attic work space
The camera is pretty basic, maximum resolution is 2592x1944 (I think this is the original 5M camera, there is also an 8M version) but does allow controlling exposure time and analog gain and can retrieve raw pixels from the sensor.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.