B4J Question RPI - changing raspistill parameters while running ? (solved)

derez

Expert
Licensed User
Longtime User
I have a non-ui application (server) that sends pictures using raspistill.
I use the following code:
B4X:
sub AppStart...
...
If ProcessIsRunning = False Then
        shl.Initialize("shl", "raspistill", Array("-o", "temp.jpg", "-t", "0", _
                    "-tl", "2000", "-w", "960", "-h", "720", "-q", "75"))
        shl.Run(-1)
    Else
        Log("raspistill is already running.")
    End If
...
end sub

Sub ProcessIsRunning As Boolean
    shl.Initialize("", "ps", Array("-a"))
    Return shl.RunSynchronous(10000).StdOut.Contains("raspistill")
End Sub

I want to change the size of the images while the app runs., but when I kill the process and run again the camera fails.
How can I do that ?

I tried to go round the problem by changing the size of the image after it is taken but couldn't find a way to do it - it is a non-ui app.

Solution: I limited the raspistill picture-taking time ("-t", "180000"), when the process ends I can restart with the required size.
I still don't know how to end raspistill process...
 
Last edited:

jmon

Well-Known Member
Licensed User
Longtime User
I still don't know how to end raspistill process...
you can do it 2 ways:

1 - Force kill: You need to get Raspistill PID:
B4X:
Dim pgrep As Shell
pgrep.Initialize("Raspistill_GetPID", "pgrep", Array("raspistill"))
then kill using the PID:
B4X:
Dim kill As Shell
kill.Initialize("Raspistill_Kill", "kill", Array("-9", PID))

2 - "Ask to kill": Kill raspistill gently:
B4X:
Dim sh As Shell
sh.Initialize("Raspistill_Kill", "pkill", Array("raspistill"))

The second option seems to not force kill the process. more about that:
The name of kill command family Is misleading - they don't really kill anything, just send signals to processes.
By default SIGTERM signal is sent, which only gently asks process to quit, but process can
choose to ignore it or handle it differently. (see man page for kill).
To force-quit a process, you have To send it a SIGKILL signal. SIGKILL cannot be ignored by the process
And in most cases results in its instant termination, without finishing tasks in progress etc.
There are few possible syntaxes To send SIGKILL, all of these are completely equivalent:
kill -9 <PID>
kill -kill <PID>
kill -s SIGKILL <pid>

You could also loop and take pictures one after the other (remove the -tl), because I see your timelapse is 2 second interval, and taking 1 picture takes 1 second:
(code is written from memory, not tested :))
B4X:
dim picNumber as int = 0

sub takePics
    dim t as timer
    t.initialize("takePic", 2000)
    t.enabled = true
end sub

sub takePic_Tick
    dim sh as shell
    sh.initialize("takePic", "raspistill", Array("-t", "1", "-o", "myImage" & picNumber & ".jpg"))
    sh.run(-1)
end sub

sub takePic_ProcessFinished (stdou ....
   picNumber = picNumber + 1
end sub

[edit] make sure you read correctly what -t does. In a timelapse, that's the time it will run the timelapse. In normal picture mode, that's the time it will wait before taking a snapshot.
 
Last edited:
Upvote 0

derez

Expert
Licensed User
Longtime User
you can do it 2 ways:

1 - Force kill: You need to get Raspistill PID:
B4X:
Dim pgrep As Shell
pgrep.Initialize("Raspistill_GetPID", "pgrep", Array("raspistill"))
then kill using the PID:
B4X:
Dim kill As Shell
kill.Initialize("Raspistill_Kill", "kill", Array("-9", PID))

2 - "Ask to kill": Kill raspistill gently:
B4X:
Dim sh As Shell
sh.Initialize("Raspistill_Kill", "pkill", Array("raspistill"))

The second option seems to not force kill the process. more about that:


You could also loop and take pictures one after the other (remove the -tl), because I see your timelapse is 2 second interval, and taking 1 picture takes 1 second:
(code is written from memory, not tested :))
B4X:
dim picNumber as int = 0

sub takePics
    dim t as timer
    t.initialize("takePic", 2000)
    t.enabled = true
end sub

sub takePic_Tick
    dim sh as shell
    sh.initialize("takePic", "raspistill", Array("-t", "1", "-o", "myImage" & picNumber & ".jpg"))
    sh.run(-1)
end sub

sub takePic_ProcessFinished (stdou ....
   picNumber = picNumber + 1
end sub

[edit] make sure you read correctly what -t does. In a timelapse, that's the time it will run the timelapse. In normal picture mode, that's the time it will wait before taking a snapshot.

Thanks, I'll try all !
 
Upvote 0
Top