cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Browse apps to extend the software in the new JMP Marketplace
Choose Language Hide Translation Bar
Craige_Hales
Super User
JSL to Control Raspberry Camera

Raspberry, bottom, and camera, top.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 AuthPuTTY dialog high lighting load/save sessions and Auth

PuTTY dialog showing private key in AuthPuTTY dialog showing private key in Auth

Login using the public/private keyLogin 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 RaspberryThe 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 commandThe 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 closedThe 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 space1/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.

 

Last Modified: Sep 18, 2019 4:43 PM