Wednesday, March 30, 2016

Tribute to Rob Ford

What everybody wants to know, is "Why did you vote for him?".  We knew he was a jolly drunk, but every politician and businessman in Canada is like that.  It has always been that way.  We have long, cold winters, and a huge amount of male depression.  Drinking has been the traditional self-medication for that.  The alternative was being a mean and nasty non-drinker like Harper.

What we didn't know was that he had become an Uber-Drunk.  Ethanol, like all the self medications for depression becomes less effective as your body becomes totally pickled.  A happy drunk like the First Prime-minister merely drinks himself to sleep every night.  But even with that, the ethanol becomes ineffective for depression, but you can't live without it.  Enter cocaine and crack.  This stuff allows you to stay up way past your bedtime, and continue the party.  It's just a close relative to caffeine, after all.

Unfortunately, you become way more than merely pickled, and quickly die at a young age.  Everyday drunks can make it way past 60 before the liver fails.

Rob Ford, nevertheless, made an impact for his few months.  He scared the heck out of sleepy politicians and bureaucracy that supports them.  I have never seen such responsiveness, and probably will never again witness it.  There is question of whether this spurt caused more good than the later badness.  I won't go into that.

I lift up a drink in tribute to this fine old drunk, and warn all the others running the country - Stay away from that white powder.  :)

Toronto Liability Issue

I find that with poor Rob Ford gone, the city bureaucracy is less responsive.  They were terrified of him!  Here's something that I hope the next activist picks up.  All the rotund old men are sliding up and down this hill, inspired by the Rob Ford Situation (early death).



ps.  I gave it to the city, and invoked the ghost of Rob Ford who will blow crack at them.  :)

Tuesday, March 29, 2016

Oklahoma starts new intense earthquake phase

Allow me to be right once in a while.  We had a few weeks of deep earthquakes, and I detected a deep mantle shift, making the New Madrid strain gauges (tiny earthquakes) sing.  Then I said we would see the earthquakes starting to rise again.  I don't rely on the seismometers to tell how deep an earthquakes is, the error bars are ridiculous.  Instead, I simply note the magnitude and the surface intensity.  Deep earthquakes don't do much on the surface.



Thus, today, we have a heck of a lot of activity.  Note the last two.  One is very deep, only giving an intensity 1, and the other is shallow, giving a 5 for the same mag.  I think the next few weeks will be mostly shallow, probably giving some good 4's or 5's.

Eventually, we will have a big surface strain event which will again ring New Madrid.  Then the earthquakes will go deep again to the mantle, since the mantle is tying up the strain.  How many times can we do this submarine act before the Big Whoops?  I don't know .

USGS Joins the March to New-Science (Philosophy)

The Big Gus has joined our favourite warmists, in fleeing physics.  Their new map is totally qualitative and can mean anything they want to mean, day to day.  Not a speck of physics.

Ever since the warmists brought out their spurious correlation, this 'new-speak science' has become just too attractive to the PR departments that now run all universities and government institutions.  The number one rule of a political organization (as in PR) is to "Never Admit You're Wrong!".  This is not the Scientific Method where the goal is to be proven wrong as many times as you are right (or maybe many more times, in my case).

The warmists started it with their pencil-thin graphs that turned out to be a victim of semantics.  Temperature not quite going up as much?  It's still always the 'warmest year ever'.  And that map is really heat energy with all the heat going into the oceans.

Now BigGus brings that to their maps.  What is 'damage'.  Now there has been too much panic "Holy Crap!" from Ms. Hough.  It only means 'cracking' in Oklahoma, or maybe just a headache.  If it meant the same in California they would be laughed out of their beach chairs.

Now, El Nino has wasted all our heat into outer space.  We are going into a 70's style cold period.  A new ice age?  As they used to say in the 70's.  Good thing they can fuddle the stats to show we are getting warmer.  The ice on my cottage lake is never going away.  :(

Monday, March 28, 2016

Oklahoma is now officially the most dangerous place in the world for earthquakes

Reference

Yes, that's right.  As Susan Hough says: "Holy Crap!"


Who knows what the units really mean?  They have totally mucked seismic hazard and risk.  Anyway, this place is due for New Madrid II, within a couple of years.  They live in the dream that they have calmed things down by cutting down the injection, but that was cut down ever since cheap oil.  I can make up plans for a tornado and earthquake proof house, anybody?

ps.  Weird.  For me, the seismic hazard is expressed as chance of certain level of PGV.  It has nothing to do with buildings or damage.  Seismic risk is when you calculate a seismic capacity in PGV, and then do the chance of exceeding it.  If everybody builds concrete domes, then seismic capacity is high and no risk.  If the buildings are concrete with empty cans, then the risk is high.

pps.  Nobody is explaining that map.  Here's a monster article.

add:  M4.2, a new round begins.

add again.  Now the busgus is watering down the panic.  They say OK is only 5 cm/s (cracking damage), and Callie it 30 cm/s (structural damage) for the same colour.  That's a crap-out.

The fun of buying directly from China

I now buy a lot of stuff directly from China.  It's easy to use Aliexpress, and keep everything under $20 if you want to stay under the arcane Canadian limit.  I have had a 100% success at getting good stuff, but recently I have suffered with the adxl345 accelerometer boards.

The local internet price is $16 for a breakout board that you know will be perfect.  But I can get them direct from China for $2.  What could go wrong?  Everything.  The first batch was all wonky after I tested them.  The second batch, with a different board, from a different seller was all perfect when I tested them using the first i2c address.  Unfortunately, they shorted when I tried the second address.   If you want to put two on a single i2c bus, which I want to do for my production accelerometer, then this is bad.

Fortunately, Google loves us, yes I know.  I found this link.  This was classic board disaster, thousands of those must have sent to the crusher, only to be saved, Sar Wars fashion, by the ingenious Chinese.  This is what you get for $2 -- rejects.  But the fix is dirt simple.  I made a mistake the first time when I thought you shorted out the R4 resistor, but that's stupid, since it is a short anyway.  You melt the solder and scratch it out, and leave an air gap.  A perfect accelerometer with the second address, when you put SDO high.  Yeah!  I'm not buying anything more because I'm in the doghouse with the wife.  And I really want a raspi zero, but you can only buy them right now in expensive kits.


Beware of Mastercard Bearing Nasty Gifts

As just proven by my daughter's card, it is now ridiculously easy for someone to make a new card from near-public info, and go on a shopping spree in Buffalo.  They don't close off travel areas any more, because their 'anti-fraud is so advanced', or so they tell me on the phone.  This is only noticed on your bill, and then you don't have a card any more for a week or two.

Make sure you have another card.  It's so easy in Buffalo because the US doesn't have many chip terminals yet, and fooling around with the mag stripe is child's play.  Anyway, expect this soon for everybody, it's just too good of a scam.  Another billion lost by the big cards, who cares?


Sunday, March 27, 2016

Geotechnical Nightmare #7

I just did this because of the huge rain coming.  The pixies haven't done much since the last time, but they are ready to sling a bridge section.  Won't be able to do in the rain.


ps. The big rain is going to miss us.

Everybody should do seismic noise tests for your house

I'm on the verge of my biggest breakthrough yet in the Mad Labs.  But first, some background.  I have said before that the soil foundation dominates seismic hazard for your house over being in California or Oklahoma.  You can be on the solid footwall of the worst earthquake California has to offer, and only be woken up by the sounds of transformers exploding down in the valley.

Similarly you can be on quicksand like High Park in a soft brick house, and have the worst risk of death in the world, even in staid old Toronto.  How do you know?  By doing a seismic noise analysis.

My new Raspberry Pi 3 will have 4 accelerometer chips chained up like a seismic array, and it will be good enough for a seismic noise test.  Basically, you run it in your house during a work day, but without people and pets stomping around.  Then you run it in your basement, or on a slab outside.  You only need an hour or so.

Then you calculate the power spectra of the noise.  A good house or concrete building will be fairly stiff at maybe 5 Hz.  So you should see a 5 Hz peak.  On the basement you should ideally see no peak, that would be very hard ground, and we are assuming the daily noise is flat.  A very bad case is that your building and ground peak are strong at 1-2 Hz.  Then you better glue down everything and get earthquake insurance.

The big mistake of earthquake engineering is that everything is sinusoidal and matching frequencies cause resonance.  Not true if you look at the physics and simulate everything with finite differences.  Then you find that matching frequencies makes one big bullwhip, with your house at snap end.  Not good.

I'll soon have it set up and try it on my house.  That's all I can do, since I live in the basement.  It will up to others to do a lot and publish the results.  The next big earthquake is the test.

ps. here's a picture with all 4 accelerometers wired up.


Oklahoma experiences deep mantle movement



A deep M3.6 earthquake indicates lower mantle motion.  More than that - the past few weeks have shown very deep earthquakes, and unusual activity at New Madrid.  Last December, a remarkable series of large earthquakes also rang New Madrid, which is the best strain gauge available in the area.

In active areas, these deep strain events happen all the time, and don't mean anything.  But the physics makes it almost impossible to happen here, yet here it is.  Had anybody bothered to image the crust they would have found a line, called the Moho, below which there is no structure, and no earthquakes.  Yet, this stuff is like Silly Putty, and is semi-rigid.

I'm only posting this because it may prove to be significant in hind-sight.  I would imagine that New Madrid would have undergone some of this before 1811.  It is essential for a large earthquake, yet it doesn't presage one.

I suspect this is a response from the December event.  Slowly, the earthquakes got deeper and applied the strain to the putty below the Moho.  It has now responded, and the earthquakes should slowly rise again.  As usual, we shall see.

Thanks to Stanford and such, OK is convinced that all this is due to volume.  A close examination of the rock mechanics (physics) shows this to not be the case.  They are continuing to inject more fresh water as the gas wells start up, and we expect a busy season.

Friday, March 25, 2016

The New Scams

Reference


I blame it all on the warmists.  They were able to use semantics and philosophy to set aside the Scientific Method and create the new Consensus Science.  Now everybody has jumped on that bandwagon.  This thing has a tiny flashlight battery and claims to be Jedi Technology.

Also it helps that 3-d printing technology can come with a realistic plastic model.  No need for computer renders.  Who would believe that?  You need something real.  :)

A little physics tells us how much oxygen we need to breathe, and the volume of water that holds that amount of oxygen.  A little more physics tells us we can't breathe pure oxygen, it's like drinking pure ethanol.  In reality we would need gills the size of a whale shark's, and a heart-lung machine to put that oxygen directly into our blood-stream.

But I wouldn't want to spoil the dream.  Nobody listens to physics anyway.  Next I expect a genuine plastic perpetual motion machine.  Wouldn't that be neat?  :)

Wait wait!  I got one for crowd funding.

Amaze your friends - Fusion Firecracker

We have perfected cold fusion and turned it hot.  Our battery rams a single hydrogen molecule down a nano-funnel to highly compress it.  It then makes a loud bang as it fuses to helium.  No radiation detected at 3 metres!   Only $100.  Order yours now!  :)

ps.  whoops, whales don't have gills!  Intelligent brains need a huge amount of oxygen to think up scams like this.  That's why that niche in the ocean (smart hunter) can only be filled by mammals breathing air.  The size of the gills would so huge that a killer whale would eat you.  :)

Wednesday, March 23, 2016

Geotechnical Nightmare #6

Now we get to the worst part of my fears.  Remember that this is a work of fiction.  My mind does not accept that any of this is actually happening.

The pixies have stopped irritating me by moving piles back and forth, and are now going for it.  They will cross the river and completely remove the toe of the slope.  If my fears are realized this will cause all the houses to visit the river.  But most likely, nothing will happen.  Unless they pin the bottom rocks with rock bolts, the same process will continue.  However, they will most likely pin a mat to the surface and that should look very pretty.  These things are mostly for political appearances.


The benefits of a certified roof

Peter and Greg Walker Contracting

My old 30 year roof has hit 25 years and needs replacing.  I look as forward to this as I do to Geotechnical Nightmares.  We had a friend of the family do to the roofing, and he was good as anybody.  But he missed all the things to get the roof to a ripe old age, such as the overhang, ventilation, and other stuff.  All have caused endless irritation.

All the neighbours have got their roofs done by the lowest bid.  One is selling and the best they can say is that there are 30 year shingles.  People I have known have had trouble with the flashings, and had to bring back the contractor again and again.  No luck if the guy takes off.  One new roof had a shingle fly off and break my basement window.  That was my excuse to get new windows, which Walker did as well.

Wouldn't it be nice if their were a CSA standard or a building code for this?  No such luck.  But the shingle makers have a certification process somewhat like Micro-suft.  There is a thick code book, and they make sure the job is done right.  This gets a full, very hard-core warranty.

If you buying a house, you should look for this, and add 20K to the price, just for the worry-free-ness.  I'm getting the job done by the above, and there is huge amount of extra construction before they even attach the shingles.  The old part of the house needs soffit vents. The chimney needs a saddle deflector, all sorts of things that nobody else would do.  Any shingle warranty has tons of fine print about these things.

So, there is a sticker shock.  But you should get some back when you sell.  I'm going with it.

ps.  they never give me anything for these promos.  :(

Tuesday, March 22, 2016

Linux - Xiomi Miwifi - Step by step

A while ago I had this router, and after endless troubles I finally got it working with openwrt.  I didn't want to fiddle with it and find out what actually worked, so I got a new one, which will act as an ac bridge for an old laptop.  These are super-cheap, order them from Aliexpress, and request them without the box.  For Canada, one at a time, and something without a box is worthless, right?

The key trouble is that the latest firmware is all in Chinese, but you get one in English.  You must write down all the steps to change the ip address, so you can put in on your main network, and use Google translate.

Use an old Linux laptop.  If you are really super-cheap enough to use this router, you have one.

Plug in the mi, and hook up an ethernet cable to the laptop.  Power on or use 'pump' to get an ip address.  It will be something like 192.168.31.52.  Now you know the router is 192.168.31.1.  Go to that with Chrome.

Yeah, it's all in English!  Not for long.

Under the Miwifi picture, you are hitting a box - ok

Next page, hit upper box, set up wifi.  In the middle box with the eyeball, enter a password over 8 characters.  Hit the bottom box.  Next page, enter the same password (easier to remember for now), in the box with the eyeball.  Hit return.

Wait for a while until the bottom bar is complete.  Hit the only box.  Remember that all this will soon be in Chinese.

On the main admin page, go to the third option on the top (Settings). Go to the third circle at the top, with lan sign (Lan settings).  The top slider switch (dhcp), turn it off.  The bottom box with the ip address, change it to something compatible with your network and unique (it doesn't yet allow to pick up and ip address)
Hit the bottom box 'save'  It will come up with a pop-up.  Hit left button (ok).  Wait until blue light comes on.
Power off.  reconnect ethernet to your main network, have a coffee, and wait for the blue light.

Now it reboots. Put away your laptop and connect the mi to your main network.

Since I'm following along right now, I find it doesn't connect to the ip number.  Repower and it still doesn't connect.  Must have been a typo.  Press reset button, connect to your laptop and do it all over again.  Have a nice reset pin handy, hold until the light flashes.

Do it all over again.  Wait for blue light.  Do it again (drat).

Do it all over again.  Remember that you used that ip address for the new Kodi box...

Have a glass of wine, and wait for the stupid blue light.

Success!  Enter the admin password.  Go to settings and status and try an update.  Site is busy. blah

Now for the Chinese.  If the stupid site is always busy, follow this.  This takes to the dev site, remember that it is a mini, and hit the right blue box under 'mini' for a download.  Manually update the mi.

Wait for the stupid blue, and go back to that ip (yeah, it didn't wipe it).  Now you have a Chinese menu.  login and get the stok number as explained in the openwrt page.  Construct the urls by going to the end of the stok number..

Things to note.  Telnet to that ip number and get into their commands.  Use this to get the miwife sysupgrade.bin.  Don't download (I did that!) but copy link address.  In the router, cd /tmp, and wget the .bin.  mv it to firmware.bin and follow their mtd command.  Have dinner.  Connect your laptop, reset the stupid thing.  Reboot your laptop.  Wait a long long time for a solid red light.

Darn thing didn't work.  Copy your dev .bin to a usb fat32 and rename it. miwifi.bin.  power, load usb, press reset until flashing.  damn light turns blue.  Start from step one, only in Chinese.  Lots of wine.

My main problem comes from not drinking enough wine.  I don't wait long enough and can't tell the difference between orange and red.  I'm waiting for some smartass saying 'I did it all the way through, once, with no wine."

Anyway the Chinese interface doesn't resemble the English, so right now I am fumbling.  My only hope is that I did this months ago.  Oh yeah, after you set the passwords, repower.  Now you are back in action.

WAIT FOR THE STUPID BLUE LIGHT!  IT TAKES FOREVER.

Connect again on the main system. Don't know that you are still in Caps lock, and reset.  :(

Oh the horror!  On the miwifi, wget was not working.  It was only grabbing a tiny bit.  I put the whole openwrt driver on a usb, then I looked as dmesg on the router.  I could then mount it and copy it to /tmp where I could activate the mtb.

ps.  Just follow the instructions, and you shouldn't get into all the trouble I did.  That's just me.  :)

pss.  Good thing we know how to do it all over again.  If you botch your configuration in openwrt, you just can't reset, because of the weird bootloader.  You have to boot with xiomi dev firmware, and start all over again.  Doing that now.

ppppps.  Doing it all over again.  I've done the access point, now I'm trying to make it into a bridge for a laptop.  One mistake and you're toast.  For instance, I bridged the lan before wifi joining, and suddenly I can't access it any more.  poohey.

final note:  The mifi cannot act as a simple transparent repeater bridge.  That requires the broadcom chip or aetheros chip.  It is only good as an ap.

Sunday, March 20, 2016

Letter to Borys

Here's my letter to my Liberal MP.  I know he'll get it to Justin right away.

me to Borys.Wrzesnewskyj
10:43 AM
Hi Borys, I'm a retired guy, and former expert on earthquakes.  I do my own blog and have about 32,000 readers around the world on google+.  Not really that much, but one thing I have been doing is developing better earthquake equipment that is super cheap and can be made by anyone.  That requires that I import development electronic chips direct from China using Aliexpress.  The unreasonable barrier is the measly $20 limit on importing these things duty-free, since I am super-cheap.  This amount hasn't been changed since I first voted.  The US has something like $100, which is why my son moved to Palo Alto.  Not really, but he is developing something really great with all the bright engineers from UofT, and couldn't do it in Canada.  He is great friends with the guy who invented the Pebble Smart Watch, who also had to escape.

The things sending these people out is Canadian fuddy-duddyness.  Do you know what corruption you have to waddle in to get a development gov't grant in Canada?  I overheard some people hiring a bagman in a restaurant and I was shocked.

Anyway, fix this one little thing, and we'll worry about bank monopolies later.  :)

Harold Asmis

Linux - Python driver for the MMA8451 accelerometer

The mma8451 is another accelerometer available for $5 that was the model for the fiendishly complex mc3610.  This must be 'west coast' and the adxl345 is 'east coast'.  Anyway, the tests put it at the same discrimination as the mc3610, but not as good as two adxl345's.  However, the calibration the $5 board is infinitely better than the cheap Chinese $2 adxl's.  If my new shipment from China is as bad as the last one, I may go with these for my dream el cheapo accelerometer.  I'm still waiting for the raspi zero to become available in volume before I move on much.  The basic idea is too have an open design that people can do themselves and then set them up in the richer houses of Oklahoma.  You'll need 'unlimited' Internet (you use Netflix a lot) and a big hunk of space in Google Drive.  I hope to get it to something like $20 of parts and an hour of labour.  It'll be fun!

Here's the main Python driver for 2g and 200 Hz.  The program samples at 100 Hz.  Once again, the spec sheet is crap and I had to fool around.  I suppose they do that to allow people to keep secrets.  I never keep secrets.  Go ahead, busgus, outdo me!

Python Driver



#This is a Python driver for the mma8451

import pigpio
from time import sleep



# mma constants

MODE_REG = 0X2a


MODE_STANDBY = 0x14
MODE_CWAKE = 0x15

pi = pigpio.pi()



#initial sequence

start = pi.bb_i2c_open(2, 3, 50000)



#Start by sending it into Standby mode, and wait a bit


#cmd_readreg =
cmd_standby = [4, 0x1d, 2, 7, 2, MODE_REG, MODE_STANDBY, 3, 0]
(count,data)  =  pi.bb_i2c_zip(2,cmd_standby)
sleep(0.004)
print "have started standby"

#This also gives a sampling of 200
#range of 2 g is default

#Finally, set mode to cwake, for readings

cmd_cwake = [4, 0x1d, 2, 7, 2,MODE_REG , 0x15, 3, 0]
(count,data)  =  pi.bb_i2c_zip(2,cmd_cwake)
sleep(0.004)

class MMA8451:
#The msb and lsb order are reversed from the adxl345 and mc3610
    def getAxes(self):
adata = [0]*6
scale_factor = 16383.0
cmd_read = [4, 0x1d, 2, 7, 1,0x1 , 2,6,6,3, 0]
(count,adata)  =  pi.bb_i2c_zip(2,cmd_read)


        x = adata[1] | (adata[0] << 8)
        if(x & (1 << 16 - 1)):
            x = x - (1<<16 p="">

        y = adata[3] | (adata[2] << 8)
        if(y & (1 << 16 - 1)):
            y = y - (1<<16 p="">

        z = adata[5] | (adata[4] << 8)
        if(z & (1 << 16 - 1)):
            z = z - (1<<16 p="">


xf = x  / scale_factor
yf= y  / scale_factor
zf= z  / scale_factor

        return {"x": xf, "y": yf, "z": zf}




if __name__ == "__main__":
    # if run directly we'll just create an instance of the class and output
    # the current readings
mma8451 = MMA8451()
 
axes = mma8451.getAxes()
print "   x = %.5fG" % ( axes['x'] )
print "   y = %.5fG" % ( axes['y'] )
print "   z = %.5fG" % ( axes['z'] )
sleep(0.01)



#close after running - pigs BI2CC 2

****************************************

The 'average' application

#!/usr/bin/python

import time
#import graphics
from mmadriv import MMA8451

from time import sleep


mma8451=MMA8451()

dt = 0.01



accxsum = 0
accysum = 0
acczsum = 0

for a in range(4,250):
axes = mma8451.getAxes()
accy = axes['y']
accz = axes['z']
accx = axes['x']
print "   accx = %.5fG" % ( accx )
print "   accy = %.5fG" % ( accy )
print "   accz = %.5G" % ( accz )

accxsum = accxsum + accx
accysum = accysum + accy
acczsum = acczsum + accz
sleep(dt)

accxavg = accxsum / 250
accyavg = accysum / 250
acczavg = acczsum / 250

print "   accxavg = %.5f" % ( accxavg )
print "   accyavg = %.5f" % ( accyavg )
print "   acczavg = %.5f" % ( acczavg )

************************************

ps. I've ordered 4 from China (cheap as the adxl345) to see if they are seconds, like my first batch.

Oklahoma earthquakes solved

Stanford has issued a bold statement.  The PR department has gone directly to 'Theory' based on one graph.  This is somewhat familiar to regular readers.



It's nice that old guys never retire, and keep making bold statements.  :)  I'm in conflict with this one, however.  There's a tiny bit of physics that one could check, if the PR department wanted to:

Pressure:  I am postulating that the Precambrian is a free drain, no amount of injection increases the pressure.  There are pressure readings.

Volume:  Volume of produced water has gone down by half due to the low oil price.  Earthquakes haven't.

Anything else?  Has anything else gone up?  How about fresh water injection?


I can't argue with this man, any more than I can argue with warmists.  Everybody is climbing the mountain and daring anybody to knock them off.  If they don't acknowledge physics, then you can't use physics against them.  :)

Friday, March 18, 2016

Linux - Pyrrhic Victory in reading the MC3610

I've been trying to get the mc3610 to work *forever*.  Now, I have finally written the Python programs to get this to work.  It doesn't help that their sample driver for Arduino is crap, or their spec sheet is inconsistent.  These guys make the Dementors look like buffoons.

So, for the Raspberry Pi, you install pigpio library.

This allows you to directly bit-bang the stupid thing.  Here's the Python driver.  I only have 2 options, and I just changed the sampling to 200 Hz without commenting, because that's where the spec is bad at 100 Hz.

#This is a Python driver for the MC3610

import pigpio
from time import sleep



# mc3610 constants

MODE_REG = 0X10
SAMPLE_RATE_1_REG = 0x11
SAMPLE_RATE_2_REG = 0x12
RANGE_RES_REG = 0x15
I2CSET_REG = 0x13

MODE_STANDBY = 0x1
MODE_CWAKE = 0x5

pi = pigpio.pi()



#initial sequence

start = pi.bb_i2c_open(2, 3, 50000)



#Start by sending it into Standby mode, and wait a bit


#cmd_readreg =
cmd_standby = [4, 0x6c, 2, 7, 2, MODE_REG, MODE_STANDBY, 3, 0]
(count,data)  =  pi.bb_i2c_zip(2,cmd_standby)
sleep(0.004)
print "have started standby"
#read to confirm
#(count, rdata) =  pi.bb_i2c_zip(2,cmd_standby)


#You must then send a command to choose i2c only (it also does spi on the same pins)
cmd_i2c = [4, 0x6c, 2, 7, 2, I2CSET_REG , 0x80, 3, 0]
(count,data)  =  pi.bb_i2c_zip(2,cmd_i2c)


#The sample rate is set by two registers (100 Hz)

cmd_sam1 = [4, 0x6c, 2, 7, 2,SAMPLE_RATE_1_REG , 0x09, 3, 0]
#cmd_sam2 = [4, 0x6c, 2, 7, 2,SAMPLE_RATE_2_REG , 0xe0, 3, 0]
(count,data)  =  pi.bb_i2c_zip(2,cmd_sam1)
#(count,data)  =  pi.bb_i2c_zip(2,cmd_sam2)

#Set range and resolution (16g, 14 bits)
#cmd_rres = [4, 0x6c, 2, 7, 2,RANGE_RES_REG , 0x25, 3, 0]

#This is 2g with 14 bits, the scale factor changes each time
cmd_rres = [4, 0x6c, 2, 7, 2,RANGE_RES_REG , 0x05, 3, 0]
(count,data)  =  pi.bb_i2c_zip(2,cmd_rres)

#Finally, set mode to cwake, for readings

cmd_cwake = [4, 0x6c, 2, 7, 2,MODE_REG , 0x05, 3, 0]
(count,data)  =  pi.bb_i2c_zip(2,cmd_cwake)
sleep(0.004)

class MC3610:

    def getAxes(self):
adata = [0]*6
scale_factor = 16383 / 2.0
cmd_read = [4, 0x6c, 2, 7, 1,0x2 , 2,6,6,3, 0]
(count,adata)  =  pi.bb_i2c_zip(2,cmd_read)


        x = adata[0] | (adata[1] << 8)
        if(x & (1 << 16 - 1)):
            x = x - (1<<16 p="">

        y = adata[2] | (adata[3] << 8)
        if(y & (1 << 16 - 1)):
            y = y - (1<<16 p="">

        z = adata[4] | (adata[5] << 8)
        if(z & (1 << 16 - 1)):
            z = z - (1<<16 p="">


xf = x  / scale_factor
yf= y  / scale_factor
zf= z  / scale_factor

        return {"x": xf, "y": yf, "z": zf}




if __name__ == "__main__":
    # if run directly we'll just create an instance of the class and output
    # the current readings
mc3610 = MC3610()
 
axes = mc3610.getAxes()
print "   x = %.5fG" % ( axes['x'] )
print "   y = %.5fG" % ( axes['y'] )
print "   z = %.5fG" % ( axes['z'] )
sleep(0.01)
axes = mc3610.getAxes()
print "   x = %.5fG" % ( axes['x'] )
print "   y = %.5fG" % ( axes['y'] )
print "   z = %.5fG" % ( axes['z'] )


#mc3610 and pigpiod stay open after this, restart everything manually

END OF FIRST BLOOD SWEAT TEARS

Now you can run a python program doing things like plotting or here, calculating the average.

#!/usr/bin/python

import time
#import graphics
from mc3610driv import MC3610

from time import sleep


mc3610=MC3610()

dt = 0.01



accxsum = 0
accysum = 0
acczsum = 0

for a in range(4,250):
axes = mc3610.getAxes()
accy = axes['y']
accz = axes['z']
accx = axes['x']
print "   accx = %.5fG" % ( accx )
print "   accy = %.5fG" % ( accy )
print "   accz = %.5G" % ( accz )

accxsum = accxsum + accx
accysum = accysum + accy
acczsum = acczsum + accz
sleep(dt)

accxavg = accxsum / 250
accyavg = accysum / 250
acczavg = acczsum / 250

print "   accxavg = %.5f" % ( accxavg )
print "   accyavg = %.5f" % ( accyavg )
print "   acczavg = %.5f" % ( acczavg )

END OF THIS CRAP

This accelerometer is marginally better than the adxl345, but not as good as two of them chained together.  The adxl345 is $2 from China, but I had difficulty buying good ones.  My second attempt is taking over a month to ship, and I pray to get them soon.  If you can find working versions then you chain a lot together for one $16 mc3610.  DON'T BUY FROM THESE CRAZY PEOPLE!

I learned that c++ is horrible, and I like Python.  The Raspberry Pi is fantastic with all the support.

ps.  The pigs library was a great thing because I can now make a second i2c from the other lines.  No need to go that 'mysterious' underneath second i2c.

Geotechnical Nightmare #5

I had thought they would have run out of things to do, but no, they were emptying bags of gravel and filling them up again.  I suppose they have to go through every bag.

**NOTE  There is no way my brain acknowledges this as real.  I am in a delusional state, and these are just images from my fanciful brain.  Nice dog.



Wednesday, March 16, 2016

Amazon Guatemala Coffee

Here's the review I wrote for it.

I'm sitting here drinking one the finest coffees I ever had. This is a huge bag of *ground* organic Guatemalan from the Antigua area. We visited that area, and the coffee right at the plantation is marginally better. Coffee grows on a tree resembling a Cherry tree, with bright red cherries. The bean is the pit. They mush it up and use the mash as compost. Then the beans are dried in the sunlight, and further processed. It's all very organic because they shade the coffee trees with larger trees, which they trim according to the season. The birds love it, and the civet cats merrily munch the cherries and poop the most expensive beans in the world. This is prime 'arabica' coffee only grown at 5,000 feet on the sides of volcanoes. You can always see a mountain smoking in the distance. Lots of earthquakes, too, so coffee is the product of a violent geology. You only use a medium roast for this grade of coffee, dark roasts were invented for the inferior 'robusta' coffee, although I do like a dark roast. Only use the Secura stainless steel French Press, and Brita filtered water. And only drink it black. It has a fine nutty taste, with a slightly sweet aftertaste. Well rounded.

Immediately upon delivery parcel it up in Foodsaver vacuum bags (All of this available on Amazon). I don't think they have Antigua beans in the large package. I had thought these were beans, since that was I was searching for. Nevertheless, it is a perfect grind for the french press.

The link is on the top.  It makes money for me.  Not that I thought of it when I ordered the coffee. :)



ps.  Use much less than you normally would or else you will feel the caffeine hit.  We're talking a very high caffeine load, dark roasting destroys a lot of it.

Friday, March 11, 2016

Oklahoma doesn't cut anything for earthquakes

Article

All the news is full of the big OK injection reductions.  They are going to cut injection by 40%  from 2014 levels.  What they don't say is that injection is already down a half from 2014 due to oil and gas prices, and the earthquakes keep coming.

They have to 'upgrade' what they inject.  They used to inject deep water from wet oil wells.  As long as that water had percolated up from the Precambrian, they they could inject all they want.  As soon as they started washing the old oil plays with fresh water they had earthquake trouble.  Oil and gas fracking all use fresh water.

To the deep Precambrian, fresh water is like a powerful acid.  Nobody seems to know that, but it is so easy to test in a lab.  This will not happen, and also nobody will map the Precambrian with old seismic reflection data tapes.  That is why this all so much fun!


Wednesday, March 9, 2016

Linux - Getting the MC3610 accelerometer to work on Raspberry Pi

Spoiler Alert - This doesn't work!

References:
https://github.com/sajingeo/i2crw
https://github.com/mcubemems/Accelerometer_MC3610



No, I haven't got is 'quite' working yet, but right now I'm sick of it, so I'll write about it.

The MC3610 is a brand new accelerometer and the breakout board has just come out.  Now, the 5 year old ADXL345 works perfectly with Python.  That's the thing about Linux, 5 year old hardware works perfectly, the new stuff never works.  Somewhere along the line the Great Linus put up his finger and carved into stone: "Linux will never support I2C repeated starts, not now, not ever!"

So that got me royally screwed, since the bums made this chip 'repeated start'.  It's great when you have multiple masters on one i2c bus, but who does that?  So drop all that kernel support and go directly to Jail, in this case ioctl commands, or bit-banging.  The Horror!

After mucking around trying to do it the easy way, I finally found 12crw, which is C code (I used C++) for bit banging.  Lot's of fun since c is a teensy weensy bit different from c++.  The reason I had to go for horrible c is that the only driver is written in c for the Arduino.  The mc3610 is a complex computer in itself, and has a heck of a lot of commands.  You just can't tell it 'Get me the damn accelerations', no you have to write specific bytes in specific registers.  The driver had all these commands.

The mc3610 c driver worked with Arduino, because of the long and horrible program 'wire.h', which, apparently, nobody can understand.  It accesses i2c at a primitive level, which is why it works.  The raspi is a sophisticated machine running full Linux.  

So I had to convert the driver to c++ and use the i2crw calls.  Here's the darn thing.

The header file.

#ifndef MC3610_h
#define MC3610_h



/*******************************************************************************
 *** CONSTANT / DEFINE
 *******************************************************************************/
#define MC3610_RETCODE_SUCCESS                 (0)
#define MC3610_RETCODE_ERROR_BUS               (-1)
#define MC3610_RETCODE_ERROR_NULL_POINTER      (-2)
#define MC3610_RETCODE_ERROR_STATUS            (-3)
#define MC3610_RETCODE_ERROR_SETUP             (-4)
#define MC3610_RETCODE_ERROR_GET_DATA          (-5)
#define MC3610_RETCODE_ERROR_IDENTIFICATION    (-6)
#define MC3610_RETCODE_ERROR_NO_DATA           (-7)
#define MC3610_RETCODE_ERROR_WRONG_ARGUMENT    (-8)
#define MC3610_FIFO_DEPTH    32
#define MC3610_REG_MAP_SIZE    64



/*******************************************************************************
 *** CONSTANT / DEFINE
 *******************************************************************************/

//=============================================
#define MC3610_INTR_C_IPP_MODE_OPEN_DRAIN    (0x00)
#define MC3610_INTR_C_IPP_MODE_PUSH_PULL     (0x01)

#define MC3610_INTR_C_IAH_ACTIVE_LOW     (0x00)
#define MC3610_INTR_C_IAH_ACTIVE_HIGH    (0x02)


/*******************************************************************************
 *** Register Map
 *******************************************************************************/
//=============================================
#define MC3610_REG_EXT_STAT_1       (0x00)
#define MC3610_REG_EXT_STAT_2       (0x01)
#define MC3610_REG_XOUT_LSB         (0x02)
#define MC3610_REG_XOUT_MSB         (0x03)
#define MC3610_REG_YOUT_LSB         (0x04)
#define MC3610_REG_YOUT_MSB         (0x05)
#define MC3610_REG_ZOUT_LSB         (0x06)
#define MC3610_REG_ZOUT_MSB         (0x07)
#define MC3610_REG_STATUS_1         (0x08)
#define MC3610_REG_STATUS_2         (0x09)
#define MC3610_REG_MODE_C           (0x10)
#define MC3610_REG_WAKE_C           (0x11)
#define MC3610_REG_SNIFF_C          (0x12)
#define MC3610_REG_SNIFFTH_C        (0x13)
#define MC3610_REG_IO_C             (0x14)
#define MC3610_REG_RANGE_C          (0x15)
#define MC3610_REG_FIFO_C           (0x16)
#define MC3610_REG_INTR_C           (0x17)
#define MC3610_REG_PROD             (0x18)
#define MC3610_REG_DMX              (0x20)
#define MC3610_REG_DMY              (0x21)
#define MC3610_REG_DMZ              (0x22)
#define MC3610_REG_XOFFL            (0x2A)
#define MC3610_REG_XOFFH            (0x2B)
#define MC3610_REG_YOFFL            (0x2C)
#define MC3610_REG_YOFFH            (0x2D)
#define MC3610_REG_ZOFFL            (0x2E)
#define MC3610_REG_ZOFFH            (0x2F)
#define MC3610_REG_XGAIN            (0x30)
#define MC3610_REG_YGAIN            (0x31)
#define MC3610_REG_ZGAIN            (0x32)
#define MC3610_REG_OPT              (0x3B)
#define MC3610_REG_LOC_X            (0x3C)
#define MC3610_REG_LOC_Y            (0x3D)
#define MC3610_REG_LOT_dAOFSZ       (0x3E)
#define MC3610_REG_WAF_LOT          (0x3F)

#define MC3610_NULL_ADDR     (0)

struct mc3610_acc_t
{
short XAxis;
    short YAxis;
    short ZAxis;    
    float XAxis_g;
float YAxis_g;
float ZAxis_g;
} ;

typedef enum
{
    MC3610_MODE_SLEEP   = 0b000,
    MC3610_MODE_STANDBY    = 0b001,
    MC3610_MODE_SNIFF      = 0b010,
    MC3610_MODE_CWAKE      = 0b101,
    MC3610_MODE_TRIG       = 0b111,
}   mc3610_mode_t;

typedef enum
{
    MC3610_RANGE_2G   = 0b000,
    MC3610_RANGE_4G   = 0b001,
    MC3610_RANGE_8G   = 0b010,
    MC3610_RANGE_16G  = 0b011,
    MC3610_RANGE_12G  = 0b100,
    MC3610_RANGE_END,
}   mc3610_range_t;

typedef enum
{
    MC3610_RESOLUTION_6BIT    = 0b000,
    MC3610_RESOLUTION_7BIT    = 0b001,
    MC3610_RESOLUTION_8BIT    = 0b010,
    MC3610_RESOLUTION_10BIT   = 0b011,
    MC3610_RESOLUTION_12BIT   = 0b100,
    MC3610_RESOLUTION_14BIT   = 0b101,  //(Do not select if FIFO enabled)
    MC3610_RESOLUTION_END,
}   mc3610_resolution_t;

typedef enum
{
    MC3610_CWAKE_SR_DEFAULT_50Hz = 0b0000,
    MC3610_CWAKE_SR_0p4Hz        = 0b0001,
    MC3610_CWAKE_SR_0p8Hz        = 0b0010,
    MC3610_CWAKE_SR_2Hz          = 0b0011,
    MC3610_CWAKE_SR_6Hz          = 0b0100,
    MC3610_CWAKE_SR_13Hz         = 0b0101,
    MC3610_CWAKE_SR_25Hz         = 0b0110,
    MC3610_CWAKE_SR_50Hz         = 0b0111,
    MC3610_CWAKE_SR_100Hz        = 0b1000,
    MC3610_CWAKE_SR_200Hz        = 0b1001,
    MC3610_CWAKE_SR_END,
}   mc3610_cwake_sr_t;

typedef enum
{
    MC3610_SNIFF_SR_DEFAULT_6Hz = 0b0000,
    MC3610_SNIFF_SR_0p4Hz      = 0b0001,
    MC3610_SNIFF_SR_0p8Hz      = 0b0010,
    MC3610_SNIFF_SR_2Hz        = 0b0011,
    MC3610_SNIFF_SR_6Hz        = 0b0100,
    MC3610_SNIFF_SR_13Hz       = 0b0101,
    MC3610_SNIFF_SR_25Hz       = 0b0110,
    MC3610_SNIFF_SR_50Hz       = 0b0111,
    MC3610_SNIFF_SR_100Hz      = 0b1000,
    MC3610_SNIFF_SR_200Hz      = 0b1001,
    MC3610_SNIFF_SR_400Hz      = 0b1010,// only for OSR = 32
    MC3610_SNIFF_SR_END,
}   mc3610_sniff_sr_t;

typedef enum
{
    MC3610_FIFO_CONTROL_DISABLE = 0,
    MC3610_FIFO_CONTROL_ENABLE,
    MC3610_FIFO_CONTROL_END,
}   mc3610_fifo_control_t;

typedef enum
{
    MC3610_FIFO_MODE_NORMAL = 0,
    MC3610_FIFO_MODE_WATERMARK,
    MC3610_FIFO_MODE_END,
}   mc3610_fifo_mode_t;

typedef struct
{
    unsigned char    bWAKE;              // Sensor wakes from sniff mode.
    unsigned char    bACQ;               // New sample is ready and acquired.
    unsigned char    bFIFO_EMPTY;        // FIFO is empty.
    unsigned char    bFIFO_FULL;         // FIFO is full.
    unsigned char    bFIFO_THRESHOLD;    // FIFO sample count is equal to or greater than the threshold count.
    unsigned char    bRESV;
    unsigned char    baPadding[2];
}   MC3610_InterruptEvent;


class MC3610{
 public:

  /* general accel methods */
  bool start();      // begin measurements
  void stop();       // end measurments
  void SetMode(mc3610_mode_t);
void SetRangeCtrl(mc3610_range_t);
void SetResolutionCtrl(mc3610_resolution_t);
void SetCWakeSampleRate(mc3610_cwake_sr_t);
mc3610_sniff_sr_t GetSniffSampleRate(mc3610_sniff_sr_t);
mc3610_resolution_t GetResolutionCtrl(void);
mc3610_range_t GetRangeCtrl(void);
mc3610_cwake_sr_t GetCWakeSampleRate(void);
mc3610_acc_t readRawAccel(void);

 private:
  short x, y, z;
mc3610_acc_t AccRaw; // Raw Accelerometer data
uint8_t readRegister8(uint8_t reg);
int16_t readRegister16(uint8_t reg);
void readRegisters(uint8_t reg, uint8_t *buffer, uint8_t len);
bool readRegisterBit(uint8_t reg, uint8_t pos);
void writeRegisterBit(uint8_t reg, uint8_t pos, bool state);
void writeRegister16(uint8_t reg, int16_t value);
void writeRegister8(uint8_t reg, uint8_t value);    
};
#endif


Note all the wonderful definitions.

The main cpp program.

#include
#include
#include
#include
#include
#include
#include

#include "MC3610.h"

#define MC3610_CFG_I2C_ADDR     (0x6C)
#define MC3610_CFG_MODE_DEFAULT     MC3610_MODE_STANDBY
#define MC3610_CFG_SAMPLE_RATE_CWAKE_DEFAULT    MC3610_CWAKE_SR_DEFAULT_50Hz
#define MC3610_CFG_SAMPLE_RATE_SNIFF_DEFAULT    MC3610_SNIFF_SR_0p4Hz
#define MC3610_CFG_RANGE_DEFAULT         MC3610_RANGE_8G
#define MC3610_CFG_RESOLUTION_DEFAULT     MC3610_RESOLUTION_14BIT
#define MC3610_CFG_ORIENTATION_MAP_DEFAULT     ORIENTATION_TOP_RIGHT_UP

int i2c_write(int file,
                            unsigned char addr,
                            unsigned char *obuff,
                            unsigned int len);

int i2c_rw(int file,
                            unsigned char addr,
                            unsigned char *obuff,
                            unsigned int olen,
                            unsigned char*ibuff,
                            unsigned int ilen);

void i2c_close(int file);
int i2c_init();
int i2c_file = 0;
extern int i2c_file;


uint8_t CfgRange, CfgResolution;

 // Read register bit
int readRegisterBit(uint8_t reg, uint8_t pos)
{
    uint8_t value;
    int readRegister8(int reg);
    value = readRegister8(reg);
    return ((value >> pos) & 1);
}

// Write register bit
void writeRegisterBit(uint8_t reg, uint8_t pos, bool state)
{
    uint8_t value;
    value = readRegister8(reg);

    if (state)
        value |= (1 << pos);
    else
        value &= ~(1 << pos);

    writeRegister8(reg, value);
}

// Read 8-bit from register
uint8_t readRegister8(uint8_t reg)
{
    uint8_t value;
   
unsigned char ottbuff[]={0x00};

unsigned char ibuffer[248];
i2c_rw(i2c_file,reg,ottbuff,1,ibuffer,1);
        value = ibuffer[0];

    return value;
}          

// Write 8-bit to register
void writeRegister8(uint8_t reg, uint8_t value)
{
    unsigned char outbuf[] = {value};
     
     i2c_write(i2c_file,reg,outbuf,1);

}

// Read 16-bit from register
int16_t readRegister16(uint8_t reg)
{
    int16_t value;
    int i2c_file;
    uint8_t vha[2];
    unsigned char ottbuff[]={0x00};

    i2c_rw(i2c_file,reg,ottbuff,1,vha,2);    

    value = vha[0] << 8 | vha[1];
    return value;
}



// Repeated Read Byte(s) from register
void readRegisters(uint8_t reg, uint8_t *buffer, uint8_t len)
{
        unsigned char ottbuff[]={0x00};

i2c_rw(i2c_file,reg,ottbuff,1,buffer,len);

        

}
  
//Set the operation mode  
void SetMode(mc3610_mode_t mode)
{
    uint8_t value;
    value = readRegister8(MC3610_REG_MODE_C);
    value &= 0b11110000;
    value |= mode;
    writeRegister8(MC3610_REG_MODE_C, value);
}

//Set the range control
void SetRangeCtrl(mc3610_range_t range)
{
    uint8_t value;    
    CfgRange = range;
    SetMode(MC3610_MODE_STANDBY);
    value = readRegister8(MC3610_REG_RANGE_C);
    value &= 0b00000111;
    value |= (range << 4)&0x70 ;
    writeRegister8(MC3610_REG_RANGE_C, value);
}

//Set the resolution control
void SetResolutionCtrl(mc3610_resolution_t resolution)
{
     uint8_t value;
     CfgResolution = resolution;
     SetMode(MC3610_MODE_STANDBY);
     value = readRegister8(MC3610_REG_RANGE_C);
     value &= 0b01110000;
     value |= resolution;
     writeRegister8(MC3610_REG_RANGE_C, value);
}

//Set the sampling rate
void SetCWakeSampleRate(mc3610_cwake_sr_t sample_rate)
{
     uint8_t value;
     SetMode(MC3610_MODE_STANDBY);
     value = readRegister8(MC3610_REG_WAKE_C);
     value &= 0b00000000;
     value |= sample_rate;
     writeRegister8(MC3610_REG_WAKE_C, value);
}

//Get the output sampling rate
mc3610_cwake_sr_t GetCWakeSampleRate(void)
{
/* Read the data format register to preserve bits */
     uint8_t value;
     value = readRegister8(MC3610_REG_WAKE_C);
     value &= 0b00000111;
     return (mc3610_cwake_sr_t) (value);
}

//Get the range control
mc3610_range_t GetRangeCtrl(void)
{
  /* Read the data format register to preserve bits */
     uint8_t value;
     value = readRegister8(MC3610_REG_RANGE_C);
     value &= 0x70;
     return (mc3610_range_t) (value >> 4);
}

//Get the range control
mc3610_resolution_t GetResolutionCtrl(void)
{
  /* Read the data format register to preserve bits */
     uint8_t value;
     value = readRegister8(MC3610_REG_RANGE_C);
     value &= 0x07;
     return (mc3610_resolution_t) (value);
}

//Initialize the MC3610 sensor and set as the default configuration
bool start(void)
{
     
     
     SetMode(MC3610_MODE_STANDBY);
     /* Check I2C connection */
     uint8_t id = readRegister8(MC3610_REG_PROD);
     if (id != 0x70)
     {
     /* No MC3610 detected ... return false */

      return false;
      }
      SetRangeCtrl(MC3610_RANGE_8G); //Range: 8g
      SetResolutionCtrl(MC3610_RESOLUTION_14BIT); //Resolution: 14bit
      SetCWakeSampleRate(MC3610_CWAKE_SR_DEFAULT_50Hz); //Sampling Rate: 50Hz
      SetMode(MC3610_MODE_CWAKE); //Mode: Active
      return true;
}

void stop()
{
      SetMode(MC3610_MODE_SLEEP); //Mode: Sleep
}

//Read the raw counts and SI units mearsurement data
mc3610_acc_t readRawAccel(void)
{
      float faRange[5] = { 19.614f, 39.228f, 78.456f, 156.912f, 117.684f}; //{2g, 4g, 8g, 16g, 12g}
      float faResolution[6] = { 32.0f, 64.0f, 128.0f, 512.0f, 2048.0f, 8192.0f}; //{6bit, 7bit, 8bit, 10bit, 12bit, 14bit}

      uint8_t rawData[6];
      readRegisters(MC3610_REG_XOUT_LSB, rawData, 6);  // Read the six raw data registers into data array
      x = (short)((((unsigned short)rawData[1]) << 8) | rawData[0]);
      y = (short)((((unsigned short)rawData[3]) << 8) | rawData[2]);
      z = (short)((((unsigned short)rawData[5]) << 8) | rawData[4]);

      AccRaw.XAxis = (short) (x);
      AccRaw.YAxis = (short) (y);
      AccRaw.ZAxis = (short) (z);
      AccRaw.XAxis_g = (float) (x) / faResolution[CfgResolution]*faRange[CfgRange];
      AccRaw.YAxis_g = (float) (y) / faResolution[CfgResolution]*faRange[CfgRange];
      AccRaw.ZAxis_g = (float) (z) / faResolution[CfgResolution]*faRange[CfgRange];

      return AccRaw;
}

The modified i2crw header file

#ifndef I2CRW
#define I2CRW

// for intel edison i2c breakout board from spakfun.com
#define I2C_FILE_NAME "/dev/i2c-1"



/**
 *  Perform a simple I2C write
 * @param addr address of the slave device
 * @param *obuff array of bytes to be writen to the slave device
 * @param len length / number of bytes to be writen to the slave device
 *  @return 1 for pass 0 fail, prints error on STDOUT
 */
int i2c_write(int file,
                            unsigned char addr,
                            unsigned char *obuff,
                            unsigned int len);

/**
 * Performs a mixed transaction I2C, START | WRITE | REPEATED START | READ
 * @param addr address of the slave device
 * @param *obuff array of bytes to be writen to the slave device
 * @param olen length / number of bytes to be writen to the slave device
 * @param *ibuff array to store the received bytes
 * @param ilen length / number of bytes to receive
 * @return 1 for pass 0 fail, prints error on STDOUT
 */
int i2c_rw(int file,
                            unsigned char addr,
                            unsigned char *obuff,
                            unsigned int olen,
                            unsigned char*ibuff,
                            unsigned int ilen);

/**
 * Initilize the I2C interface and returns a number for the file system handle
 */

int i2c_init();

/**
 * close / release resource for the I2C bus
 * @param file the file system handle for the initilazed I2C
 */
void i2c_close(int file);




#endif

and finally the main program, still using the mc3610 header.

/**
 * @file   i2crw.c
 * @Author sajin.geo@gmail.com
 * @date   Jan 12th 2015
 * @brief  API for using the repeated start feature of the I2C bus
 *
 * Wraper library to i2c. based on the work of Sean Cross / chumby industries , Copyright (c) 2010, released under BSD licence
 */
#include
#include
#include
#include
#include
#include
#include
#include
#include "i2crw.h"

extern int i2c_file;

int i2c_write(int file,
                            unsigned char addr,
                            unsigned char *obuff,
                            unsigned int len) {
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[1];
    messages[0].addr  = addr;
    messages[0].flags = 0;
    messages[0].len   = len;
    messages[0].buf   = obuff;
    
    packets.msgs  = messages;
    packets.nmsgs = 1;
    if(ioctl(file, I2C_RDWR, &packets) < 0) {
            perror("Unable to send W data");
            return 1;
    }
    return 0;
}

int i2c_rw(int file,
                            unsigned char addr,
                            unsigned char *obuff,
                            unsigned int olen,
                            unsigned char*ibuff,
                            unsigned int ilen) {
struct i2c_rdwr_ioctl_data packets;
   struct i2c_msg messages[2];
   
   // tx message
   messages[0].addr  = addr;
   messages[0].flags = 0;
   messages[0].len   = olen;
   messages[0].buf   = obuff;
   
   // rx message
   messages[1].addr  = addr;
   messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
   messages[1].len   = ilen;
   messages[1].buf   = ibuff;
   
   packets.msgs      = messages;
   packets.nmsgs     = 2;
   
   if(ioctl(file, I2C_RDWR, &packets) < 0) {
           perror("Unable to send RW data");
           return 1;
       }
    return 0;
}


int i2c_init()
{

if ((i2c_file = open(I2C_FILE_NAME, O_RDWR)) < 0) {
       perror("Unable to open i2c control file");
       exit(1);
   }
return 0;
}


void i2c_close(int file)
{
close(file);
}



//int main(int argc, char **argv) {
// int i2c_file,i=0;
// unsigned char ottbuff[]={0x00};
// unsigned char outbuf[]={0x00,0xB8,0x0D,0x1F,0x74};
// unsigned char ibuffer[248];
// // Open I2C file
// i2c_file = i2c_init();
//
//
//
// if(i2c_write(i2c_file,0x60,outbuf,5))
// {
// printf("unable to write to register");
// }
//
// if (i2c_rw(i2c_file,0x50,ottbuff,1,ibuffer,248))
// {
// printf("unable to read from register");
// }
// for (i=0;i<=248;i++)
// {
// printf("%x ",ibuffer[i]);
// }
//
// i2c_close(i2c_file);
//    return 0;
//}


Note that it has a sample 'main' which I used in mc3610

I've compiled each of these into '.o' object files, and I'm about to mash the thing together.  Maybe I'll do it tomorrow.  I had hoped to work slow enough that somebody would take this on, but nobody seems to have the board yet.  

When is works (yeah!), the mc3610 should be much more sensitive than two adxl345 summed together, I hope.  I did learn a lot about c++, more than I want to know.  :)

ps.  It turns out that driver is total b*llsh*t.  It sends the wrong values.  I got through using manual bit-banging and am now writing that in Python.

Sunday, March 6, 2016

Geotechnical Nightmare Part 4

I had to get this in before the big flood.


ps.  right now it is getting warm.  The snow could melt gently, and the land is fairly dry.  No flood yet.

Friday, March 4, 2016

Geotechnical Nightmare Part 3



Not much happening in my brain.  The pixies are just trying to drive me nuts by not doing anything.

Wednesday, March 2, 2016

Oklahoma earthquakes fixated



Recently, they have all been at one spot.  This was a 4.3 that just happened.  Most appear to be quite deep, as their intensities are quite low.  I have no idea as to what could be happening.  When they are this deep, no fluid is touching them, they are a response to regional stresses.  I had expected earthquakes to propagate up to the NE but this isn't happening.  We'll have to wait.

There is a limit to how much strain energy can be released at one spot.  This just has to mean something ominous.  :)

ps.  deep normal earthquake, indicating compression and longitudinal cracking.  Every earthquake here has been like that, they just had an m3.5