INTERACT FORUM

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1] 2 3   Go Down

Author Topic: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!  (Read 69317 times)

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291

The mad professor has been at work again. :)

I managed to get a portable MC20 server running on a Pi2 with 500GB 2TB HDD and about 6-8hrs battery life in a small tidy little box.
I call it the Pi "Brick" Media Center.  

I'll be finishing it on the weekend and tidying it up a bit. I'll take to the case with the Dremel to fit external ports, leds. power etc.
Pics and video of assembly and demo below. :)











Here's the complete youtube playlist for the Pi2 Brick MC20. I'll update this as I make further developments.
<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?list=PLidW7ho7KcuCxXGSU0l_5MV6w4shFxIYn" frameborder="0" allowfullscreen></iframe>


Part 1 Video
<iframe width="560" height="315" src="https://www.youtube.com/embed/bM5nhlm_Y4M" frameborder="0" allowfullscreen></iframe>
https://www.youtube.com/watch?v=bM5nhlm_Y4M

Part 2 Video
<iframe width="560" height="315" src="https://www.youtube.com/embed/xtzarC_IqyQ" frameborder="0" allowfullscreen></iframe>
https://www.youtube.com/watch?v=xtzarC_IqyQ

Part 3 Video
<iframe width="560" height="315" src="https://www.youtube.com/embed/KlYi4SwEmfc" frameborder="0" allowfullscreen></iframe>
https://www.youtube.com/watch?v=KlYi4SwEmfc



Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291

I think you're gonna love this!

I got the Pi2 to do a few things with the GPIO3 pin to manage MC20 in headless mode.

I can restart MC20, Reboot or shutdown all with a momentary button attached to GPIO3.

I have a timer setup to measure the button press time to execute the various commands.

It's a heavily modified GPIO actions script.
I'll also be setting up a hard reset button too with the "Run" pins.
So in headless mode I'll have a few options to reset or power off gracefully.

The Pi can corrupt the SD card if you don't shutdown gracefully so it's important to have some way of shutting down cleanly.

I have:
2 sec press to kill and restart MC20
5 sec press to reboot
10 sec press to shutdown
And a separate hard reset button

I might play with the timings a bit still.  
I can probably add some LEDs to other GPIO pins to indicate status, stuff like, MC20 running, playing, Bluetooth active, wifi connected, all sorts of things including playback control buttons. :)


Here's the GPIO script I saved to /home/pi/raspi_gpio_actions_INT2.py
I also added this script to the crontab @ reboot with crontab -e so it executes every reboot.

Run crontab -e to edit crontab
Code: [Select]
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
@reboot /etc/MC20start.sh
@reboot sudo /home/pi/raspi_gpio_actions_INT2.py

/home/pi/raspi_gpio_actions_INT2.py
Code: [Select]
#!/usr/bin/env python2.7

from time import sleep
import os
import subprocess
import RPi.GPIO as GPIO

CHANNEL = 3 # GPIO channel 3 is on pin 5 of connector P1
# it will work on any GPIO channel

GPIO.setmode(GPIO.BCM)
GPIO.setup(CHANNEL, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# setup the channel as input with a 50K Ohm pull up. A push button will ground the pin,
# creating a falling edge.


def system_action(CHANNEL):
    print('Button press = negative edge detected on channel %s'%CHANNEL)
    button_press_timer = 0
    while True:
            if (GPIO.input(CHANNEL) == False) : # while button is still pressed down
                button_press_timer += 1 # keep counting until button is released
            else: # button is released, figure out for how long
                if (button_press_timer > 10) : # pressed for > 10 seconds
                    print "long press > 10 : ", button_press_timer
                    # do what you need to do before halting
                    subprocess.call(['shutdown -h now "System halted by GPIO action" &'], shell=True)
                elif (button_press_timer > 4) : # pressed for > 4<10 seconds
                    print "medium press > 4 : ", button_press_timer
                    # do what you need to do before rebooting
                    subprocess.call(['sudo reboot &'], shell=True)
                elif (button_press_timer > 2) : # press for > 2 < 4 seconds
                    print "short press > 2 < 4 : ", button_press_timer
                    # do what you need to do before restarting mediacenter20
                    subprocess.call(['./RestartMC20.sh & echo "Killing MC20" &'], shell=True)
                button_press_timer = 0
            sleep(1)

GPIO.add_event_detect(CHANNEL, GPIO.FALLING, callback=system_action, bouncetime=200)
# setup the thread, detect a falling edge on channel 3 and debounce it with 200mSec

# assume this is the main code...
try:
    while True:
        # do whatever
        # while "waiting" for falling edge on port 3
        sleep (2)

except KeyboardInterrupt:
    GPIO.cleanup()       # clean up GPIO on CTRL+C exit
GPIO.cleanup()           # clean up GPIO on normal exit


And here's the MC20 restart subprocess script (you cant call a user level subprocess within a root script without some funky scripting so this was a quick work around)

\home\pi\RestartMC20.sh
Code: [Select]
pkill -f mediacenter20
echo Restarting mediacenter20
export DISPLAY=:0
/bin/su pi -c mediacenter20
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291

The Prototype is coming along nicely. Better get that cheque book ready Jim! :) LOL
 
Somehow I have to fit all this into the case. By a great fluke of luck it looks like it will actually fit by reorienting a couple things!


External add on ports:
1x HDMI out
1x 3.5mm Stereo jack out
1x Power in/charge
1x HDD USB out

External Pi2 ports:
1x USB wifi
1x USB BT
1x USB HDD loopback
1 x Ethernet
1x spare USB

Add on Switches and LEDs:
1x Power on/off switch
1x Momentary On switch for combined Status toggle/Restart MC/Reboot/Shutdown using the timer script
1 x RGB LED for Pi status during boot and maybe other status reporting (using quick press on the momentary switch to toggle status)
3 x LEDs for front panel - (Blue power/Green MC running/Red HDD)
3 x LEDs for battery status

Yet to be decided:
Button controls for Play, Pause, Stop, FFD/REW, Volume (These can certainly be added but I may have to fabricate a circuit with surface mount switches for this once I know how much space I have left)
A small screen, maybe though that's getting a bit hard to fit now.
Fitting a DAC, though I'm not sure it's worth the effort or I'll have space.

I'll also start development on another prototype based on the standard case with micro switches and LEDs once I get this one working the way I want it.
Maybe Jim can sell the case with an optional lid/case with the buttons and leds or wouldn't mind me selling them as add-ons.

I'd ultimately like to miniaturise both designs as small as possible and design my own brushed metal cases similar in look to the FiiO stuff with some circuit board designs and surface mount switches and LEDs to shrink everything down.
I'd like to make the larger brick case with a user removable HDD slot and battery.  That would be cool.

Well I'm off to tinker....  ;D

The collection of components and development bits.
The add-on external ports are keystone mounts that I'll figure out a way to mount cleanly.






As you can see I'll be cutting it fine fitting it all in, but by re-orienting the Pi and sliding the battery under it I have the room I need for the additional external ports. (just)



Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291

Yeah it fits!

I'll be making cutting templates and dremelling my little heart out tomorrow. :)

Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291

Here's my first proper attempt at GPIO control of MC20 on the Pi2.
So far I can restart MC20 and get the LED flashing to indicate it's received the signal and is rebooting.
The LED goes out when the command was successful.
I also have the reboot switch working which was less of a challenge.


https://www.youtube.com/watch?v=bpzQME_Gwg8
Logged

JimH

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 72362
  • Where did I put my teeth?

Where will it stop?  ;)  Cool stuff.

I added the embed link.
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291

Thanks I cant do embedded links can you please do the 3 above too. Cheers!
 :)

BTW it's my pleasure to tinker with this stuff.  I'll make you a MC20 player you'd be proud to sell! :)



Logged

JimH

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 72362
  • Where did I put my teeth?

You should be able to add [ html ] and [ /html ] (with no spaces) before and after the link you get from Youtube.

I look forward to your future episodes.
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291

The html tags get stripped and deleted for me. I'm pretty sure I've mentioned this before, I don't think general users can post html by default because its a security risk. (I do have some html knowledge so I don't think Im being dumb, I actually copied the code from your edit and it strips the html tags when its posted.

Maybe you can get my permissions changed. :)

Here's the complete youtube playlist for the Pi2 Brick MC20.  I'll update this as I make further developments.
<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?list=PLidW7ho7KcuCxXGSU0l_5MV6w4shFxIYn" frameborder="0" allowfullscreen></iframe>
Logged

lepa

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 2033

Cool!  8)
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #10 on: March 15, 2015, 06:31:07 am »

I decided to work a little more on the layout and mounting method today with cables in-place before I start cutting and I've now got it sorted.
Everything fits where I need it to fit with a little space to spare.

The battery will mount in the top of the case with the main power button and battery LEDs.

The Pi2 will mount from under the bottom panel with 4 small stand offs.
The HDD will also mount from under the bottom panel with 4 long screws through hollow stand offs.
The 4 keystones will be glued into cutouts in the top cover.
The Pi2 will also have a cutout in the top cover for it's USB and Ethernet port.

I'll have main power button and reset switch on the back panel next to the keystone ports one above the other.
I'll have the main power LED, HDD and MC status lights on the front panel.

I'll probably have to make a super short HDMI cable but I can buy the short OTG cables for everything else internally.











Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #11 on: March 16, 2015, 05:36:10 am »

The final design and layout is almost done! But, I'd like some input on port locations before I put the case under the dremel!

What do you guys think would be more aesthetic and practical? (excuse the messy bluetac holding things in place!)
Ports all on long side at the back (case length ways), or ports on the short side at the back, with pi ports on left (case depth ways?)

See the Vid and Pics below.

https://www.youtube.com/watch?v=ht1xwWpxaEY











Ports all on long side.



Logged

bob

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 13811
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #12 on: March 16, 2015, 01:26:01 pm »

I like the ports all along the long side.
Logged

mwillems

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 5233
  • "Linux Merit Badge" Recipient
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #13 on: March 16, 2015, 01:59:47 pm »

I like the ports all along the long side.

Me too
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #14 on: March 17, 2015, 05:17:40 am »

Thanks guys that was my preference too.

I have the case assembled and complete now, just need to add the LEDs and switches, drill the mounting holes for the Pi and HDD and the prototype is finished.
It was a very tight fit but it worked out exactly as planned!

There's small air gaps between the HDD, the battery, and the Pi, but I think I'll have to cut some ventilation holes too.

I thought I may have a real challenge with assembly but things just slotted together nicely in the end.

I'll finish the rest tonight and take some more pics before I start road testing it over the next couple weeks to see how reliable it is and how hot it gets.
I've been using it in the car fully enclosed in the case for a week and notice it can get quite warm.

I'll start having a look around at options to make a more refined case now, whether that means 3D printed cases, laser cut acrylic, or metal fabrication or a combination I'm not sure yet.
What do you guys think?

https://www.youtube.com/watch?v=CAJIgg50fuc

It's not quite a slice yet, but I haven't asked for US$300,000 to design and build it and it wont cost US$280 either!
I think the guys that backed slice are bonkers and have wasted their money.

https://www.kickstarter.com/projects/fiveninjas/slice-a-media-player-and-more

Not much to see here!














Logged

mwillems

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 5233
  • "Linux Merit Badge" Recipient
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #15 on: March 17, 2015, 09:42:43 am »

There's small air gaps between the HDD, the battery, and the Pi, but I think I'll have to cut some ventilation holes too.

I thought I may have a real challenge with assembly but things just slotted together nicely in the end.

I'll finish the rest tonight and take some more pics before I start road testing it over the next couple weeks to see how reliable it is and how hot it gets.
I've been using it in the car fully enclosed in the case for a week and notice it can get quite warm.

I'll start having a look around at options to make a more refined case now, whether that means 3D printed cases, laser cut acrylic, or metal fabrication or a combination I'm not sure yet.
What do you guys think?

A metal case will be more expensive (and harder to work with), but will solve your heat dissipation problem much better than ventilation holes.  As tightly packed as you've got everything in there, ventilation slots may not be enough to dissipate the heat, so your next step in passive cooling is an aluminum case.  That's basically what Flirc did with their pi case (turned the whole case into a heatsink).
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #16 on: March 17, 2015, 07:31:38 pm »

A metal case will be more expensive (and harder to work with), but will solve your heat dissipation problem much better than ventilation holes.  As tightly packed as you've got everything in there, ventilation slots may not be enough to dissipate the heat, so your next step in passive cooling is an aluminum case.  That's basically what Flirc did with their pi case (turned the whole case into a heatsink).

I found the right case for the job. It's a little pricey @ about $25, but that's pretty good for an extruded aluminium case. :)
It has a sliding removable belly plate and they do screen printing, drilling and milling to spec too.

I'll get one to check if everything fits and then go from there to work out if it's feasible to get them made pre-cut for the cut-outs I need.
My CAD skills are a bit rusty but I'll give it a shot. ( I did some CAD work and metal fabrication and machine work in the late 80's :o )

http://www.dlpc.com.au/ham/pdf/1455N1601.pdf

PS. might be better off going with the slightly larger version so I can mount all the ports on the short side and it'll be easier to machine the end plates.

http://au.rs-online.com/web/p/general-purpose-enclosures/7733003/




Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #17 on: March 18, 2015, 03:22:27 am »

Pi2 Take II - Miniaturising the Pi2 Media case.
Yes we can make it smaller!

https://m.youtube.com/watch?v=E1ut6P6OVIQ
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #18 on: March 18, 2015, 04:28:50 am »

Here's a teaser shot of it working with a standard SSD with a USB 3 adapter. :)
That means you can use any standard Sata drive and it can have the slot removable drive that I wanted.

It all fits!

Because of all the electrical connections at the back I've decided I'll cut most of the back panel off the metal cover, and fit a plastic back piece that will be easy and cheap to get made up with all the cutouts.
Then I just have to drill a couple holes mount a couple LEDs and switches and that's about it.

I'll put a thin layer of insulation (microtherm) between the battery and the CPU to keep them thermally isolated.
I'll turn the case into a heat sink for the HDD and battery and make a metal heatsink for the CPU that extends and attaches to the case.

Finish the brushed metal look on the lid of the case, coat it with a protective layer and/or colour so the brushed metal look still shows through.
Screw a couple rubber feet into it...

One sexy battery powered Pi2 Media Center with SSD or HDD. :) How many would you like to order?  ;D




Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #19 on: March 20, 2015, 12:07:22 pm »

It's almost finished.  
Everything is properly mounted now.

I just have to drill a couple holes for switches, and another LED or 2 and rewire the battery and the hard part is done!

I've ordered a short HMDI cable and I'll mount a power jack at the back and headphone(lineout) socket at the front.
The power switch from the battery will be on the lid in the center near the front.








Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #20 on: March 21, 2015, 09:00:44 am »

Looking very steampunked in its naked aluminium now.  :)  I like it but I'll still paint it with a semi sheen black.

I found a battery with more capacity (6000mAh) that fits much better today and the charging circuit layout allowed me to mount the micro usb charging socket with direct access from the back.  That should give it an extra couple hours or so.  All the ports apart from the headphone/line-out port are at the back.

Not quite up to the look of the FiiO, but I don't think it looks too bad, and it'll look even better when painted.

I only have a few bits of wiring to do now and it'll be finished enough to use while I wait for the HDMI cable and work on the back panel.













Plenty of clearance. :)





Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #21 on: March 21, 2015, 09:37:58 am »

Now it's time to start building a DAC and an AMP to go with it. I may even use the same case. :)
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #22 on: March 22, 2015, 01:28:22 am »

99% finished - Stress Testing for a week before I make any more decisions around extra controls and cutting or painting the case.

More Pics and Videos on the way.

If anyone has any suggestions before I make the final changes I'm all ears!



Demo
https://www.youtube.com/watch?v=VLM5V6JLfY8



Video of Inside
https://www.youtube.com/watch?v=2dgkL1ZcBqs



Pics of Inside















Logged

jmone

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 14399
  • I won! I won!
Re: Pi2 "Brick" JRiver Media Center - Battery powered 500GB portable MC20!
« Reply #23 on: March 22, 2015, 02:17:24 am »

Looks good, I'll bring my around and we can marvel at it all.  One thing I found in my Ghetto setup is powering a Tablet, DAC, and Amp from the one DC power supply = ground hum....
Logged
JRiver CEO Elect

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #24 on: March 24, 2015, 05:25:47 am »

I Installed a Samsung Spinpoint m9t 2TB drive this afternoon.  Really quiet, low power consumption and fast. :)

http://www.storagereview.com/samsung_spinpoint_m9t_hard_drive_review
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #25 on: March 25, 2015, 06:27:52 am »

I have the controls working on a breadboard with MCC commands via GPIO pins and I've started prototyping the control board for the front panel and can fit 2 rows of buttons. (4 or 5 each row)
I also have the option of fitting another 2 buttons on the top cover on the left edge or on the left side at the front
Unfortunately the front panel or the top cover at the front are the only locations I can fit buttons or switches.

Possible button locations:





I was thinking of player control buttons << > x >> for the top row and maybe volume for the two far right buttons on the bottom row with a mute just to the left. 
That leaves 1 or 2 spare for reboot and restart MC which I can recess so you have to make a more deliberate attempt to press them.

Im not really sure If I should bother including player controls as I don't really need them or the volume controls, but I do still want to at least fit a reboot and MC restart.
I've found matching tiny chromed button caps to make the controls look a bit fancier.

Button Caps:



I've also found a power-on / controlled shutdown module with switch that I can fit which includes an IR sensor. I'll fit it to the left of the control board.
I've also got a small RTC board so the Pi keeps the time.

So what do you think? Should I mess up the front panel with controls or just stick to the bare minimum?
Are there controls that you think would be more useful to have for running in headless mode?

Other options I've considered are:
WPS Wifi button to join a network
BT pairing button
Logged

BryanC

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 2643
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #26 on: March 25, 2015, 10:20:06 am »



I've always liked no buttons (that instead exist on a remote or only via a headless interface) because it means I can hide the thing away when necessary. If you want me to nitpick, I'd say the same thing about the toggle switch. It's nicer to have the power control via the power plug because then I can extend power-on/power-off away from the player if it is hidden. MC updates could easily be handled on the next startup.
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #27 on: March 28, 2015, 12:10:46 am »

As much fun as it's been getting mc controls to work via buttons I'm starting to lean the same way. Less is more.
I've been playing music from the Pi2 for probably 30hours this week and I haven't missed controls apart from a shutdown and the need to restart MC via SSH a couple times.
When my power module arrives i think I'll just put a small power off and restart MC button on the top and a tiny Blue led for power and a green led to show that MC is running, along with a small opening for an IR sensor. That should tidy up the front.
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #28 on: March 29, 2015, 04:30:53 am »

Not much to report.  The Pi2 and case has been working really well the last week.  I'm getting between 5-7hrs out of the battery and it doesn't get too hot even after 4hrs of continuous play.

I did rewire power yesterday so now it has uninterrupted power capability.  I can have the power plugged in, switch to battery and vice versa, without powering down.  This is handy in the mobile context where I use it at home, in the car and in the office.  When ever I've got power available I can switch over to mains and charge the battery and then go back to battery.  It's not automated yet but it can be with a little more work. For the moment I still have to remember to switch the battery on or off, but it's great to have the portability with continuous playback.

I've got really short 10cm/4" USB 3 HDD cables and SATA to USB dongles on the way for the HDD which will tidy the back ports a little more. They should arrive mid week.

This week I'll finalise the design for the LED's, RTC, switches and power circuit.  I've decided to leave the playback controls out for now as I've been using JRemote to control it just fine and I've never missed having controls on the case.
I'll still include a discrete minimalist shutdown button and restart MC20 button though.  The power LEDs will indicate whether it's on mains or battery and there'll be battery level indicators too.

Oh and I milled the lip off the back of the case now so the HDD can slide in and out without having to take the unit apart.

Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #29 on: April 05, 2015, 09:56:11 am »

I've sorted out what's taken the most research!  The darn HDMI connection!!!
The cables I ordered were still too stiff and thick to fit.

After hours and hours and trawling websites I've found these HDMI FFC cables. They're darn expensive so I'll have to source the individual parts and make my own PCBs if i'm going to even think about mass production.



I've ordered some LiPo charge and converter boards from adafruit to finalise the power circuit.
So It will now have hot swap UPS power between mains and battery and automatically charge when plugged in or switch to battery without rebooting.
It'll also automatically shutdown cleanly when battery gets low.







I've ordered some nice really small blue LED tactile switches to replace the toggle and led with a single tiny led lit switch.
With the new compact HDMI connection I'll have room to move the 3.5 stereo jack to the rear and have a really clean front panel with just the led switch.




I started designing a case in CAD (how tedious!) and MC20 on the Pi2 has been running great!


Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #30 on: April 10, 2015, 09:48:28 am »

Still waiting on a few more small pieces of the puzzle but the new powersupply works really well.
The internals are very nearly finished now.

I don't get any power brownouts at all any more with the new power circuit and I can plug and unplug the power without rebooting and it automatically charges when plugged in.
I got a new 4A 5V powerpack shipped with the internal power circuit with an inline switch too. :)

PS. I'm using this several hours every day in the car and in the office and it hasn't missed a beat going between the office and the car without having to reboot.
I love it!







Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #31 on: April 12, 2015, 10:11:45 am »

Tonight I finished working on my GPIO control scripts and have a single button to restartMC, reboot and shutdown. The LED shows when its finished booting and turns off to show when it safe to turn off the main power switch. I have it all assembled and working and will make a new video demo tomorrow.

Things left to do:
A couple better smaller switches.
A better smaller LED.
Fit the realtime clock somewhere.
Fit a battery level indicator somewhere.
Still waiting on my super thin HDMI cable.
Still waiting on delivery of some super short micro USB3 HDD cables.
Make a back panel.
Smaller rubber feet.
A paint job.

Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #32 on: April 12, 2015, 10:14:55 pm »

Getting a bit toasty @ 60c with the new layout and no heatsink on the CPU.  No stability issues but that's a bit warm, and the case is about 40-45c to touch.
Will have to make a heatsink to transfer the CPU heat to the case.  The HDD and battery operating temps are up to 60c and the HDD is also sitting at about 43c.  :o



SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x002f   100   100   051    Pre-fail  Always       -       0
  2 Throughput_Performance  0x0026   252   252   000    Old_age   Always       -       0
  3 Spin_Up_Time            0x0023   087   082   025    Pre-fail  Always       -       4000
  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       200
  5 Reallocated_Sector_Ct   0x0033   252   252   010    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x002e   252   252   051    Old_age   Always       -       0
  8 Seek_Time_Performance   0x0024   252   252   015    Old_age   Offline      -       0
  9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       165
 10 Spin_Retry_Count        0x0032   252   252   051    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       217
191 G-Sense_Error_Rate      0x0022   100   100   000    Old_age   Always       -       5
192 Power-Off_Retract_Count 0x0022   252   252   000    Old_age   Always       -       0
194 Temperature_Celsius     0x0002   062   057   000    Old_age   Always       -       38 (Min/Max 19/43)
195 Hardware_ECC_Recovered  0x003a   100   100   000    Old_age   Always       -       0
196 Reallocated_Event_Count 0x0032   252   252   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0032   252   252   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0030   252   252   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0036   200   200   000    Old_age   Always       -       0
200 Multi_Zone_Error_Rate   0x002a   100   100   000    Old_age   Always       -       0
223 Load_Retry_Count        0x0032   100   100   000    Old_age   Always       -       2
225 Load_Cycle_Count        0x0032   100   100   000    Old_age   Always       -       2043
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #33 on: April 13, 2015, 05:35:25 am »

Here's the new look with combined switch and Blue LED ring.






Here's the rather crowded looking internal shot with most of the wiring done.  





Only a few things left to do.
I have to fit and wire the RTC and battery indicator and there's still some space left believe it or not!  I may even be able to fit an I2C DAC with analog out.
Im still waiting on my HDMI cable.  :(

I like the switch with the blue circle led so much Im going to replace the power switch and green LED with another combined green LED main power switch.

Please excuse the bluetac holding things in place. It is a prototype after all. :)
Logged

6233638

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 5353
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #34 on: April 13, 2015, 05:38:27 am »

I don't check the Linux forum very often, so I only just saw this - very impressive build, and it looks like it would be a fun project to do.
I look forward to seeing the finished product.
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #35 on: April 13, 2015, 07:14:25 am »

Yes it certainly is a lot of fun!

Here's the demo video of the new multifunction LED switch and the UPS.

https://www.youtube.com/watch?v=D5R_SZvNZ-E
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #36 on: April 14, 2015, 08:14:02 am »

I went with red LED main power switch, I didn't like the colour of the green.
It's slightly recessed as it's an instant momentary on/off power button that I don't want to accidently turn it off.

In the final prototype I'll recess the blue LED switch the same as the red one, though that's not as important as you have to hold the centre button for at least 2 secs to trigger anything.

The photos don't do it justice, they're a really nice crisp blue and red.

Power on and still booting up


Booted up



Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #37 on: April 15, 2015, 09:03:15 am »

Here's a quick photoshop colour change.

Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #38 on: April 16, 2015, 10:18:44 am »

 ;D pi M8888T

Logged

JimH

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 72362
  • Where did I put my teeth?
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #39 on: April 16, 2015, 10:31:59 am »

Ta da!
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #40 on: April 17, 2015, 12:32:13 am »

Yes it's nearly finished. Only took 4 weeks from concept to this point and there's not much design work to be done now. (and most of that time was waiting for parts)

Just starting to work out real parts costs to source them more cost effectively and the best way to assemble and produce the end product in batches of 10 or 20 as either kits or complete assembled units.

It may not be financially viable as a product but it's been fun. :)

I've been posting bits of the worklog on a couple of other forums, AVS/Head-Fi/Raspberry Pi/ADAfruit and Overclockers here in OZ and there is some interest in something like this, both as just a case in a kit form and as an assembled unit.  I have most interest from the OZ overclock forums with almost 2000 reads and the most comments and thumbs up, Head-fi has been good too.

The guys at ADAfruit have been very helpful and supportive too.
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #41 on: April 19, 2015, 09:04:08 pm »

The short micro USB3 to USB and SATA to USB cables arrived.

Looks a bit tidier now.

Micro USB3 to USB







SATA to USB




Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #42 on: April 21, 2015, 09:40:55 am »

Just trying to track down a voltage drop problem on the new charger circuit.  Made this video for the ADAfruit support.

https://www.youtube.com/watch?v=bjvhfrp9SCM


Battery Volts




Load Volts (should be the same or very slightly less allowing for losses in the circuit.)


Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #43 on: April 24, 2015, 06:03:19 am »

Still trying to sort out power issues with the new power circuit.  Have put the original standard USB charger back in and I don't have voltage drop. If adafruit cant advise on what can be done to fix or adjust the solar charger I'll be sorted. 

The solar charger has proper load sharing to charge the battery and run the Pi at the same time where as the USB charger doesn't, so the battery wont charge with the standard USB charger with power plugged in while the Pi is running.  I may have to find another power circuit to use, though it useable as is, it's not ideal.

I measured and it's only drawing 1A under normal load, peaking to 1.3A.
I have a video below of the standard USB charger in circuit measuring current during boot and peak load is 1.3A.
Very little voltage drop with the USB charger and 4V on the battery, with only about .15v voltage drop where as the solar charger drops to 2.9V and a bit lower at the peak 1.3A load.

Playing and decoding 3x 96k FLAC files simultaneously also draws about 1.2-1.3A at 50-60% utilisation. (load split pretty evenly over 4 cores)
This is with Wifi, BT dongle, USB HDD direct off Pi USB and a self powered DAC.  No brownouts occurring with USB charger but I do get brownouts with the solar charger at peak load.

I'll be making the next version of the case this weekend and am going to try to make cutouts for the rear ports on the metal case with my makeshift Dremel CNC machine.

https://www.youtube.com/watch?v=Gn5kcwJoNZY
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #44 on: April 25, 2015, 05:10:43 am »

Still working through the power issue with adafruit support.  They're sending me free powerboost 1000 combined with a charger to see if it behaves the same in my circuit.

I did however this evening get the battery monitoring working.

I got the sparkfun Lipo fuel gauge working with the Adafruit_I2C scripts on the Pi with the Adafruit USB charger. Should work with the Solar charger too.
It was pretty simple. Hook up the fuel gauge SDA (data) and SCL (clock) to Pi pins 3 (SDA) and 5 (SCL).
Charger Battery terminals connected to the JST on the fuel gauge.

Here it is measuring a very slow charge while the Pi is running with an almost flat battery.
First without power plugged in you can see it discharge and then with power plugged in, very slowly charging.

I installed the Adafruit I2C scripts and libraries and the fuel.py script from here> https://bitbucket.org/widefido/fuel/src

Code: [Select]
pi@raspberrypi ~/Adafruit-Raspberry-Pi-Python-Code/Adafruit_I2C $ sudo python fuel.py
estimated time left: 0h 0m 0s (1.27%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.17%)
estimated time left: 0h 0m 0s (1.12%)
estimated time left: 0h 0m 0s (1.12%)
estimated time left: 0h 0m 0s (1.12%)
estimated time left: 0h 0m 0s (1.12%)
estimated time left: 0h 0m 0s (1.10%)
estimated time left: 0h 0m 0s (1.10%)
estimated time left: 0h 0m 0s (1.10%)
estimated time left: 0h 0m 0s (1.08%)
estimated time left: 0h 0m 0s (1.05%)
estimated time left: 0h 0m 0s (1.07%) **charging**
estimated time left: 0h 0m 0s (1.07%)
estimated time left: 0h 0m 0s (1.08%) **charging**
estimated time left: 0h 0m 0s (1.08%)
estimated time left: 0h 0m 0s (1.10%) **charging**
estimated time left: 0h 0m 0s (1.10%)
estimated time left: 0h 0m 0s (1.12%) **charging**
estimated time left: 0h 0m 0s (1.12%)
estimated time left: 0h 0m 0s (1.12%)
estimated time left: 0h 0m 0s (1.13%) **charging**
estimated time left: 0h 0m 0s (1.13%)
estimated time left: 0h 0m 0s (1.13%)
estimated time left: 0h 0m 0s (1.15%) **charging**
estimated time left: 0h 0m 0s (1.15%)
estimated time left: 0h 0m 0s (1.15%)
estimated time left: 0h 0m 0s (1.15%)
estimated time left: 0h 0m 0s (1.17%) **charging**
estimated time left: 0h 0m 0s (1.17%)
estimated time left: 0h 0m 0s (1.17%)
estimated time left: 0h 0m 0s (1.18%) **charging**
estimated time left: 0h 0m 0s (1.18%)
estimated time left: 0h 0m 0s (1.18%)
estimated time left: 0h 0m 0s (1.18%)
estimated time left: 0h 0m 0s (1.18%)
estimated time left: 0h 0m 0s (1.20%) **charging**
estimated time left: 0h 0m 0s (1.20%)
estimated time left: 0h 0m 0s (1.20%)
estimated time left: 0h 0m 0s (1.20%)
estimated time left: 0h 0m 0s (1.20%)
estimated time left: 0h 0m 0s (1.20%)
estimated time left: 0h 0m 0s (1.21%) **charging**
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)
estimated time left: 0h 0m 0s (1.21%)



Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #45 on: May 01, 2015, 01:59:29 am »

I haven't worked anymore on the solar charger issues yet, but the standard USB charger board is working well anyway at the moment. The Pi2 will either maintain current charge or slowly charge with the USB based charger. (incase you're wondering why on earth I would use a solar charger, it's because the solar charger has a proper load sharing circuit which directs more charging current to the battery when the power's plugged in and the Pi is running.)

I did get my low battery scripts working today though, which was a major break through for me! :)  Just a bit of tidying up to do.

I can't take credit for the base code, I've just adapted it for my needs.
This script will normally be set with 10% battery as the warning level where it will write a warning file and @ 5% it will write a shutdown file which the other script will detect and then shutdown - still have to add the flashing LED for warning but that should be straight forward from here.

Here's the output of the battery monitor script with the low battery set to 70%
 
Code: [Select]
pi@raspberrypi ~/Adafruit-Raspberry-Pi-Python-Code/Adafruit_I2C $ sudo ./fuel.py
Battery Low: 50.01%
Setting Low Battery Status
estimated time left: 0h 25m 36s (49.62%)
timestamp: 2015-05-01 16:12:39.991583
threshold: 4
alert: 32
volts: 3.6239
Battery Remaining: 49.62%
Battery Low: 49.62%
Setting Low Battery Status
estimated time left: 0h 51m 13s (49.62%)
timestamp: 2015-05-01 16:12:55.004299
threshold: 4
alert: 32
volts: 3.6422
Battery Remaining: 49.62%
Battery Low: 49.62%
Setting Low Battery Status

Here's the output of the lowbattery detection script
Code: [Select]
pi@raspberrypi ~ $ clear
pi@raspberrypi ~ $ sudo ./lowbatt.py
Low Battery Detected
Low Battery Detected
Low Battery Detected



Here's the battery monitor script

Code: [Select]
#!/usr/bin/python

"""
A library for reading from a MAX17043 lithium battery fuel gauge over I2C

"""
from __future__ import print_function

import Adafruit_I2C
import os
import subprocess
import argparse
import datetime
import time

I2C_BUS = 1
FUEL_ADDRESS = 0x36

VCELL_REGISTER   = 0x02
SOC_REGISTER     = 0x04
MODE_REGISTER    = 0x06
VERSION_REGISTER = 0x08
CONFIG_REGISTER  = 0x0C
COMMAND_REGISTER = 0xFE

wire = Adafruit_I2C.Adafruit_I2C(0x36, busnum=I2C_BUS)

def writeReset():
    """ reset the fuel guage """
    return writeRegister(COMMAND_REGISTER, 0x00, 0x54)

def writeQuickStart():
    """ set the fuel guage to quick start mode """
    return writeRegister(MODE_REGISTER, 0x40, 0x00)

def writeAlertThreshold(threshold):
    """ set the alert threshold % between 1 and 32 """
    msb, lsb = readRegister(CONFIG_REGISTER)
    threshold = max(1, min(32, threshold)) # threshold between 1 & 32
    threshold = 32 - threshold
    return writeRegister(CONFIG_REGISTER, msb, (lsb & 0xE0) | threshold)

def readVCell():
    """ read the voltage of the battery """
    msb, lsb = readRegister(VCELL_REGISTER)
    value = (msb << 4) | (lsb >> 4)
    return mapValue(value, 0x000, 0xFFF, 0, 50000) / 10000.0

def readSOC():
    """ read the "state of charge" (% remaining) of the battery """
    msb, lsb = readRegister(SOC_REGISTER)
    return msb + lsb/256.0

def readVersion():
    """ read the fuel guage version """
    msb, lsb = readRegister(VERSION_REGISTER)
    return (msb << 8) | lsb

def readCompensatedValue():
    """ read the battery chemistry compensated value """
    msb, lsb = readRegister(CONFIG_REGISTER)
    return msb

def readAlertThreshold():
    """ read the current alert threshold (%) """
    msb, lsb = readRegister(CONFIG_REGISTER)
    return 32 - (lsb & 0x1F)

def readAlert():
    """
    read whether or not the battery is "in alert" / below the alert threshold

    """
    msb, lsb = readRegister(CONFIG_REGISTER)
    return lsb & 0x20

def readRegister(address):
    """ utility function for reading 2 bytes from a register address """
    return wire.readList(address, 2)

def writeRegister(address, msb, lsb):
    """ utility function for writing 2 bytes to a register address """
    return wire.writeList(address, [msb, lsb])

def mapValue(x, in_min, in_max, out_min, out_max):
    """ utility function for mapping a value from one range to another """
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

def watch(interval=15, eol_percent=10, max_n=120):
    """
    watch the battery consumption using a modified moving average of the
    state of charge and estimate the time remaining at the current usage.

    """
    prev_soc = None
    diff_mma = 0
    diff_n = 0
    charging = False

    while True:
        # get the current state of charge
        soc = readSOC()
        if prev_soc is None:
            prev_soc = soc

        # compute the difference between the current and previous soc reading
        diff = soc - prev_soc
        if diff <= 0:
            charging = False
        else:
            charging = True

        # compute a modified moving average of the rate of usage
        diff_mma = mma(diff, mma_yesterday=diff_mma, n=diff_n)
        diff_n = min(diff_n + 1, max_n) # only weight max_n observations (this should helps with lar$
        prev_soc = soc

        if diff_mma != 0:
            ttl = ((soc-eol_percent)/-diff_mma)*interval # how many seconds until we reach 10%?
            h, m, s = split_seconds(ttl)
            print("estimated time left: {0}h {1}m {2}s ({3:.2f}%){4}".format(int(h), int(m), int(s),$
            print("timestamp: {0}".format(datetime.datetime.now()))

     if prev_soc is None:
            prev_soc = soc

        # compute the difference between the current and previous soc reading
        diff = soc - prev_soc
        if diff <= 0:
            charging = False
        else:
            charging = True

        # compute a modified moving average of the rate of usage
        diff_mma = mma(diff, mma_yesterday=diff_mma, n=diff_n)
        diff_n = min(diff_n + 1, max_n) # only weight max_n observations (this should helps with lar$
        prev_soc = soc

       if diff_mma != 0:
            ttl = ((soc-eol_percent)/-diff_mma)*interval # how many seconds until we reach 10%?
            h, m, s = split_seconds(ttl)
            print("estimated time left: {0}h {1}m {2}s ({3:.2f}%){4}".format(int(h), int(m), int(s),$
            print("timestamp: {0}".format(datetime.datetime.now()))
            print("threshold: {0}".format(readAlertThreshold()))
            print("alert: {0}".format(readAlert()))
            print("volts: {0}".format(readVCell()))
            print("Battery Remaining: {0:.2f}%".format(readSOC()))

        if (readSOC()) >= 70:
            print("Battery OK: {0:.2f}%".format(readSOC()))
            subprocess.call(['rm /tmp/lowbatt &'], shell=True)
        else:
            print("Battery Low: {0:.2f}%".format(readSOC()))
            subprocess.call(['touch /tmp/battlow & echo "Setting Low Battery Status" &'], shell=True)

        # sleep until the next reading
        time.sleep(interval)

def mma(observation, mma_yesterday=0, n=0):
    """
    Compute the modified moving average for a series of observations.

    Formally:
  print("alert: {0}".format(readAlert()))
            print("volts: {0}".format(readVCell()))
            print("Battery Remaining: {0:.2f}%".format(readSOC()))

        if (readSOC()) >= 70:
            print("Battery OK: {0:.2f}%".format(readSOC()))
            subprocess.call(['rm /tmp/lowbatt &'], shell=True)
        else:
            print("Battery Low: {0:.2f}%".format(readSOC()))
            subprocess.call(['touch /tmp/battlow & echo "Setting Low Battery Status" &'], shell=True)

        # sleep until the next reading
        time.sleep(interval)

def mma(observation, mma_yesterday=0, n=0):
    """
    Compute the modified moving average for a series of observations.

    Formally:

        MMAtoday = (((N-1) * MMAyesterday) + observation) / N

        (which is, in short, an exponential moving average with alpha=1/N)

    """
    if n == 0:
        return observation
    return (((n-1) * mma_yesterday) + observation) / (n)

def split_seconds(seconds):
    """ split seconds into hours, minutes, and seconds """
    seconds = int(seconds)
    if seconds < 0:
        return 0, 0, 0
    hours = seconds/3600
    seconds = seconds % 3600
    minutes = seconds / 60
    seconds = seconds % 60
    return hours, minutes, seconds

def dump():

   """ dump the current state to stdout """
    print("timestamp: {0}".format(datetime.datetime.now()))
    print("version: {0}".format(readVersion()))
    print("compensated: {0}".format(readCompensatedValue()))
    print("threshold: {0}".format(readAlertThreshold()))
    print("alert: {0}".format(readAlert()))
    print("vcell: {0}".format(readVCell()))
    print("soc: {0:.2f}%".format(readSOC()))

if __name__ == "__main__":
    try:
        watch()
    except KeyboardInterrupt:
        print()


Here's the rather simple low battery detection script. I was going to do all this with hardware GPIO pins but this is simpler and more elegant because it doesn't require any more wiring and allows me to use mostly the existing scripts.
As a backup I'll still have hardware level low battery detection which will do a hard shutdown in case of a system crash.

Code: [Select]
#!/usr/bin/python

import os
from time import sleep
import subprocess
import os.path

while True:
    if os.path.isfile('/tmp/battlow'):
        print "Low Battery Detected"
    else:
        print "Battery OK"
    sleep(15)

try:
    while True:
        # do whatever
        sleep(2)

except KeyboardInterrupt:
    print("Exit")
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #46 on: May 01, 2015, 11:13:55 am »

I contacted J0rdan Sherer the author of the Fuel library and he was very modest!

He gave me a quick tip that should point me in the right direction below. Thanks J0rdan!

Quote
Thanks for reaching out. I wrote this for a personal project of mine: http://restoringmylibretto.tumblr.com/ and never expected somebody else might want to use it. Otherwise, I probably would have written some better documentation!

Anyway, the script was generally only used as a battery level / "time remaining" estimator. It reads the SOC level from the battery in a loop and computes the estimated time remaining based on a modified moving average of the current battery consumption. As long as consumption was fairly steady, this estimated the time remaining for my project usually at 90% accuracy. I rarely used it to write the values to the MAX17043.

Anyway, if you don't want to use the script as a simple battery monitor, but would rather use it to write the threshold level, you can do that by using the writeThreshold function. You can either modify the script itself to call that function, or import it from another script or the python interactive command. Something as simple as this from another script should work:
import fuel
fuel.writeThreshold(16)

Otherwise, you could set the threshold at the beginning of the watch function.
Logged

Hilton

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 1291
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #47 on: May 03, 2015, 08:22:01 am »

The good news is I have all my scripts working now.  The bad news is, I still haven't worked out how to make use of the kill switch feature on the power switch to completely turn power off when battery gets low.

I can either get down to Halt with a clean shutdown or trigger a kill switch hard shutdown, but I'd like to do a kill switch as the last thing before HALT so that I can completely turn the power off.
I've spent soooo much time on just the power side of this, curse you battery powered devices! It's so much simpler when it's just a power switch to mains with a shutdown switch!

Any way here's where Im up to in case any bright spark here has an idea how to achieve what I want.

First a tiny bit more background. (please excuse the untidy code im still learning as I go!)

Im using an Adafruit Push-button Power Switch Breakout on the RPi2B for power on and power off and I have a sparkfun fuel gauge to monitor the LiPo battery. The switch works as intended for normal power on and off, and it has a kill switch feature. If you put 1to3v on the kill switch pin it also shuts off the power.

I'd like to use the kill switch to power off the Pi with the alert pin from the fuel gauge. (this way its also a last line of defence to shut power off if the Pi hangs)
When the battery gets low the fuel gauge alert pin goes from 3.3v to 0 volts. (which is actually the opposite of what I want - it makes sense to work this way though because otherwise it would further flatten he battery) What this means though is that I have to use GPIO pins on the Pi to detect the alert pin going low and then shutdown. 

I have all the scripts working when manually triggered but I cant work out how to trigger the kill switch after the Pi has shutdown or even just before the final halt command.

Is there anyway to pull a GPIO output pin high at shutdown.(just before or even after HALT)
I've tried adding a script to the rc0.d just before HALT.
I moved K10halt to K50halt and added my script as K10poweroff with symlink to the below script, but im guessing I cant use python at this stage of the shutdown.

If there's another way to do this I'd love to know.
I figure worst case I could edit the default pin behaviour in the Pi device tree but Im still new to this stuff and would prefer not to have pins default to an output unless I have no other choice.
Thanks!

Here's my main GPIO button script.

Code: [Select]
#!/usr/bin/env python2.7

from time import sleep
import os
import subprocess
import RPi.GPIO as GPIO

BUTTON1 = 17 # GPIO channel 17 - RestartMC/Shutdown/Reboot
LED1 = 26 # GPIO channel 26 - Power LED
BATTERY1 = 16 # GPIO channel 16 - Low Battery
POWEROFF1 = 22 # GPIO channel 22 - Power off kill switch

GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON1, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(LED1, GPIO.OUT, pull_up_down=GPIO.PUD_UP)
GPIO.output(LED1, 1)
GPIO.setup(BATTERY1, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(POWEROFF1, GPIO.OUT, pull_up_down=GPIO.PUD_DOWN)


def button_action(BUTTON1):
    print('Button press = negative edge detected on Button %s'%BUTTON1)
    button_press_timer = 0
    while True:
            if (GPIO.input(BUTTON1) == False) : # while button is still pressed down
                button_press_timer += 1 # keep counting until button is released
            else: # button is released, figure out for how long
                if (button_press_timer > 7) : # pressed for > 10 seconds
                    print "long press > 7 : ", button_press_timer
                    # do what you need to do before halting
   subprocess.call(['sudo reboot &'], shell=True)
                elif (button_press_timer > 3 < 7) : # pressed for > 4<10 seconds
                    print "medium press > 3 < 7 : ", button_press_timer
                    # do what you need to do before rebooting
   subprocess.call(['./RestartMC20.sh & echo "Killing MC20" &'], shell=True)
                elif (button_press_timer > 1 < 3) : # press for > 2 < 4 seconds
                    print "short press > 1 < 3 : ", button_press_timer
                    # do what you need to do before restarting mediacenter20
   subprocess.call(['shutdown -h now "System halted by GPIO action" &'], shell=True)
button_press_timer = 0
            sleep(1)

def battery_monitor(BATTERY1):
#    batt_timer = 0
    while True:
        if (GPIO.input(BATTERY1) == True) : # while batt is ok
         batt_timer = 0
       print "batt Ok"
   else: # batt is low
          print "Battery Low Detected - Checking"
       batt_timer += 1 # keep counting
          if (batt_timer > 60) : # batt low for > 60 seconds
         print "Battery Low For More Than 60 Seconds Shutting Down: "
#    subprocess.call(['shutdown -h now "System halted by Low Battery GPIO action" &'], shell=True)
        sleep(1)

GPIO.add_event_detect(BUTTON1, GPIO.FALLING, callback=button_action, bouncetime=200)
GPIO.add_event_detect(BATTERY1, GPIO.FALLING, callback=battery_monitor, bouncetime=200)
# setup the thread, detect a falling edge on channel 3 and debounce it with 200mSec


# assume this is the main code...
try:
    while True:
        # do whatever
        # while "waiting" for falling edge on port 3
        sleep (2)

except KeyboardInterrupt:
    GPIO.cleanup()       # clean up GPIO on CTRL+C exit
GPIO.cleanup()           # clean up GPIO on normal exit


Here's the battery monitor script
Code: [Select]
#!/usr/bin/python

import os
from time import sleep
import subprocess
import os.path

while True:
    if os.path.isfile('/tmp/battlow'):
        print "Low Battery Detected"
    else:
     print "Battery OK"
    sleep(15)

try:
    while True:
        # do whatever
        sleep(2)

except KeyboardInterrupt:
    print()


Here's the final poweroff script im trying to run just before halt.
Code: [Select]
#!/usr/bin/python

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

POWEROFF = 22

GPIO.setup(POWEROFF, GPIO.OUT, pull_up_down=GPIO.PUD_UP)
GPIO.output(POWEROFF, 1)

Oh and here's the excerpt of my code changes to the fuel gauge script.
Code: [Select]
if (readSOC()) >= 4:
print("Battery OK: {0:.2f}%".format(readSOC()))
subprocess.call(['rm /tmp/lowbatt &'], shell=True)
else:
print("Battery Low: {0:.2f}%".format(readSOC()))
subprocess.call(['touch /tmp/battlow & echo "Setting Low Battery Status" &'], shell=True)


Logged

mwillems

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 5233
  • "Linux Merit Badge" Recipient
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #48 on: May 03, 2015, 08:52:10 am »

I have no good advice, but can offer my sympathy.  That exact "reverse-bootstrap" issue is something I grappled with in trying to handle Pi-turn-offs and it's one that the community doesn't have a great solution for even outside of the battery context. 

Ultimately I think trying to script a solution will be a dead-end because if you can still run a script, the OS is still operating, which means the filesystem is still being accessed and the sd card is still running wear-levelling, which means there's still a risk of filesystem corruption.  It's a chicken and egg problem.

One mitigation solution is to make the filesystem read-only and run the OS in RAM (https://wiki.debian.org/ReadonlyRoot).  That will solve half the problem of sdcard corruption (eliminate system writes), so just cutting power without a halt won't be quite as catastrophic.  But that doesn't solve the other half of the problem, which is SD card wear-leveling, and I know of no way to solve that issue without a proper halt.

The only real solutions I can think of involve external hardware/electronic solutions.  For example: I have a powerstrip that senses when power draw on one outlet goes below a certain threshold for more than a second or two, and then closes a relay cutting power to the rest of the strip.  If you could setup a circuit like that which would trigger based on the Pi itself's decreasing powerdraw during a halt, you'd solve your own problem.  Unfortunately, I have no idea how to design such a circuit, but I know it's possible  ;D
Logged

RoderickGI

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 8186
Re: Pi2 "Brick" JRiver Media Center - Battery powered 2TB portable MC20!
« Reply #49 on: May 03, 2015, 09:56:25 pm »

When the battery gets low the fuel gauge alert pin goes from 3.3v to 0 volts.

I think MWillems has the solution, sort of. You can't do it in scripts. You have to do it in hardware. It sounds like you need a simple transistor circuit that detects the 3.3v to 0v drop, and sends a pin high to shutdown the Pi via the Kill Pin on the Adafruit Push-button Power Switch Breakout. That is what transistors do.

Unfortunately I'm not an electronics engineer so I can't advise how to actually do that. But I would guess there are a heap of examples on the internet.

Thinking about it though, I would first investigate if there was another pin on the sparkfun fuel gauge that goes high instead of low, or if a small modification would provide such a pin. I would ask the supplier/designer about that.
Logged
What specific version of MC you are running:MC27.0.27 @ Oct 27, 2020 and updating regularly Jim!                        MC Release Notes: https://wiki.jriver.com/index.php/Release_Notes
What OS(s) and Version you are running:     Windows 10 Pro 64bit Version 2004 (OS Build 19041.572).
The JRMark score of the PC with an issue:    JRMark (version 26.0.52 64 bit): 3419
Important relevant info about your environment:     
  Using the HTPC as a MC Server & a Workstation as a MC Client plus some DLNA clients.
  Running JRiver for Android, JRemote2, Gizmo, & MO 4Media on a Sony Xperia XZ Premium Android 9.
  Playing video out to a Sony 65" TV connected via HDMI, playing digital audio out via motherboard sound card, PCIe TV tuner
Pages: [1] 2 3   Go Up