Out of the box, the stock debian distro for my Beaglebone Black didn't recognize my Edimax USB wifi adapter. But after plugging it into wired ethernet and doing an apt-get update ; apt-get dist-upgrade, it shows up just fine.
I got it to associate with an access point once, but I got a lot of packet loss, and haven't gotten it to work since. After an hour or two of fiddling, I'm just going to buy a different adapter.
Update: Looks like "ifconfig wlan0 up" gets it to associate with an AP. See http://credentiality2.blogspot.com/2015/09/getting-beaglebone-black-and-green-to.html
Tuesday, September 08, 2015
Friday, September 04, 2015
Arduino Due: toggle open drain GPIO pin
I wanted a pin on my Arduino Due to switch between pulling down toward ground and turning off (going high impedance).
I tried using pinMode(x, INPUT);, but there's a bug in the arduino libraries that sets the output high when I switch back to pinMode(x, OUTPUT). That's no good!
So I read up in the datasheet and found the register that enables open drain mode. The pinout was also handy so I could see that pin 53 (according to Arduino) is port B, pin 14 according to the ARM chip.
Here's the code snippet.
I tried using pinMode(x, INPUT);, but there's a bug in the arduino libraries that sets the output high when I switch back to pinMode(x, OUTPUT). That's no good!
So I read up in the datasheet and found the register that enables open drain mode. The pinout was also handy so I could see that pin 53 (according to Arduino) is port B, pin 14 according to the ARM chip.
Here's the code snippet.
// Sketch for Arduino Due that enables open drain mode for pin B14
void setup() {
pinMode(53, OUTPUT);
digitalWrite(53, 0);
// Enable open drain mode on pin 14 of port B using the Multi-Driver Enable Register
REG_PIOB_MDER = 1 << 14;
// To switch it back to a normal output:
// REG_PIOB_MDDR = 1 << 14;
}
void loop() {
// Turn on B14 (should be about equivalent to digitalWrite(53, 1))
REG_PIOB_SODR = 1 << 14;
// Pause 1ms so it's easy to see on the scope
delay(1);
// Turn off B14
REG_PIOB_CODR = 1 << 14;
// Pause 2ms
delay(2);
}
Wednesday, September 02, 2015
libfann bugs
Looking for a general purpose neural network library, fann seemed reasonable. Jury's still out, but I see a number of shortcomings:
- I see people warning against using its builtin input/output scaling. So make sure your training set (inputs and outputs) is all scaled to [0,1]
- fann_create_train(...) shows up in the docs but doesn't appear to actually exist (version 2.1.0)
- I see no examples of fann_create_train_from_callback(), and the docs are unclear, but it looks like it allocates the memory itself and then calls the callback num_data times. So the num_data value that gets passed to the callback is 1..n, and the two pointers point directly to the elements to be filled in.
- #include <doublefann.h> with gcc -lfann caused data corruption for me, because the internal library calls had fann_type = float while my main program had fann_type = double. So either use #include <fann.h> with gcc -lfann or #include <doublefann.h> with gcc -ldoublefann!
Saturday, June 13, 2015
Simple pump from a juice bottle
In some cars, the only way to add or check transmission fluid is to remove a hard-to-reach plug and add fluid until it starts pouring out the hole. Since the hole is in the side of the transmission, there's no way to get a funnel into the hole. You have to pump the fluid into the hole.
Auto parts stores will sell you a pump, but I discovered that all I needed was a water bottle and some tubing. Drill two holes in the cap for the tubes, fill the bottle about halfway with fluid and force air into the short tube. I was worried about air leaking between the hole and the tubing, but it came out just right, nice and tight. It can still work without a perfect seal but it'll require more air.
This tubing was the perfect diameter to thread into the nozzle of the air gun on my compressor, but I think it would have worked just as well to simply blow into the short tube. (I tried it with water just now and it seemed to work fine, but watch out for fumes and don't let any fluid come back up the short tube!)
The tubing shown here is for the ice maker in my fridge.
The tubing shown here is for the ice maker in my fridge.
Thursday, May 28, 2015
Mary Meeker Internet Trends 2015
http://kpcbweb2.s3.amazonaws.com/files/90/Internet_Trends_2015.pdf
Slides of interest to me:
p.47: 6 of top 10 mobile apps are for messaging
p.68: Social network use in 12-24 year olds: Instagram 32%,Twitter 24%, Facebook 14% (down from 35% in 2013)
p.69: 78% of millennials spend >2h per day on smartphone
p.70: 44% of millennials use smartphone camera at least once / day
p.103: Americans receiving government benefits 50% in 2012 vs. 30% in 1983.
p.110: #2 top work value for millenials is "Flexible Working Hours"
p.113: Millenials seen as more narcissistic, open to change, creative than Gen X
p.117: USA Smartphone penetration 64%
p.132: 72% of NYC airbnb hosts depend on it for rent/mortgage
p.163: 7% of Xaomi phone buyers (China) buy a Xaomi home product
p.165: India starting to take off in Internet penetration (very cool chart)
p.169: India #2 in % of internet traffic via mobile
p.170: 41% of India e-commerce is via mobile
Slides of interest to me:
p.47: 6 of top 10 mobile apps are for messaging
p.68: Social network use in 12-24 year olds: Instagram 32%,Twitter 24%, Facebook 14% (down from 35% in 2013)
p.69: 78% of millennials spend >2h per day on smartphone
p.70: 44% of millennials use smartphone camera at least once / day
p.103: Americans receiving government benefits 50% in 2012 vs. 30% in 1983.
p.110: #2 top work value for millenials is "Flexible Working Hours"
p.113: Millenials seen as more narcissistic, open to change, creative than Gen X
p.117: USA Smartphone penetration 64%
p.132: 72% of NYC airbnb hosts depend on it for rent/mortgage
p.163: 7% of Xaomi phone buyers (China) buy a Xaomi home product
p.165: India starting to take off in Internet penetration (very cool chart)
p.169: India #2 in % of internet traffic via mobile
p.170: 41% of India e-commerce is via mobile
Monday, March 23, 2015
Steam Linux audio problems
No audio at all from steam games? Try 'pavucontrol'. It'll show you when games are trying to play audio and where they're playing it to. In the "configuration" tab I had to disable built-in audio and switch my "HDA NVidia" device to "Digital Surround 5.1 (HDMI) Output" from "Digital Stereo (HDMI) Output".
Sunday, March 22, 2015
GQL to CSV exporter for Google App Engine
The App Engine admin panel will let you run GQL queries against your datastore, but it won't let you download the results as a CSV. So I wrote a [very] quick and [very] dirty handler that does, which also has the handy side effect that you can put your own access controls on it. That means you can give someone on your team read-only access to your datastore without also giving them access to the admin panel.
If you're using db instead of ndb, I believe the main thing to change is ndb.gql() to GqlQuery().
If you're using db instead of ndb, I believe the main thing to change is ndb.gql() to GqlQuery().
# Very quick and dirty example of how to provide unfettered read
# access to your datastore with export to CSV. Be sure to add appropriate
# access controls and watch out for security risks (like XSS)
#
# Don't forget to:
# from google.appengine.ext import ndb
# from google.appengine.ext.ndb import metadata
class GqlPage(webapp2.RequestHandler):
def get(self):
limited = True
row_limit = 1000
# Tricky to distinguish absence of 'limit' checkbox when you
# first hit the URL from when you submitted with an unchecked box
if self.request.get('download', 'nope') != 'nope' and \
self.request.get("limit", "nope") == "nope":
limited = False
query = self.request.get('query', "empty")
is_csv = False
if self.request.get('download') == 'Download':
is_csv = True
self.response.headers['Content-Type'] = "text/csv"
else:
self.response.write('<html><body>')
self.response.write('<form action="/gql" method=POST>')
self.response.write('<textarea name=query rows=10 cols=80 placeholder="select * from...">')
if query != "empty":
self.response.write(cgi.escape(query))
self.response.write('</textarea><br>')
self.response.write("<input type=submit name=download value=View>")
self.response.write('<input id=foo type=submit name=download value=Download')
self.response.write(' onclick="document.getElementById(\'results_div\').innerHTML=\'\';">')
self.response.write("Limit response to " + str(row_limit) + " rows:")
self.response.write("<input name=limit type=checkbox ")
if limited:
self.response.write("checked")
self.response.write('><br></form>')
self.response.write("Examples for available tables:<br>")
for kind in metadata.get_kinds():
self.response.write("select * from " + kind + "<br>")
self.response.write('<br><div id="results_div"><pre>')
if query != 'empty' and query != '':
results = []
if limited:
results = ndb.gql(query).fetch(row_limit)
else:
results = ndb.gql(query).fetch()
writer = csv.writer(self.response.out)
row_count = 0
first_row = True
for row in results:
row_dict = row.to_dict()
keys = sorted(row_dict.keys())
# Write column labels as first row
if first_row:
first_row = False
self.response.write("#")
writer.writerow(keys)
values = []
for k in keys:
value = str(row_dict[k])
if is_csv:
values.append(value)
else:
values.append(cgi.escape(value))
writer.writerow(values)
row_count += 1
if not is_csv and limited and row_count == row_limit:
self.response.write("\n[Truncated at " + str(row_limit) + " lines]")
if not is_csv:
self.response.write('</pre></div>')
self.response.write("</body></html>")
def post(self):
return self.get()
Subscribe to:
Posts (Atom)