Archive for the ‘Programming’ Category

Perl bluetooth communications

Friday, May 20th, 2022

I had a couple of notes on using Net::Bluetooth from a raspberry pi to talk to a Bluetooth serial port because I couldn’t get the example code given with Net::Bluetooth to work.

The following will connect to a mac address and send and receive data from it (in this particular example, a ESP32):


#!/usr/bin/perl

use Net::Bluetooth;
use Data::Dumper;
use IO::Handle;
my $obj = Net::Bluetooth->newsocket(“RFCOMM”);

$addr = ‘C4:4F:33:58:B6:FB’;
$port = 1;

if($obj->connect($addr, $port) != 0) {
die “connect error: $!\n”;
}

my $fh = $obj->perlfh();
$fh->autoflush(1);

sleep(1);

print “sending \n”;

print $fh “V\n”;
print “receiving\n”;

$buf = readline($fh);
print “Fetchhost: $buf\n”;

RabbitMQ websocket URL wrong in documentation

Monday, February 21st, 2022

Just sticking this here in the hopes that it will get listed in google and maybe save some folks a little time.

If you are trying to use rabbitMQ’s websocket STOMP connector, as discussed on https://www.rabbitmq.com/stomp.html, be aware that the URL given in the documentation on this page is wrong (or perhaps only applies to newer versions of rabbitmq).

The correct way to successfully create a websocket to RabbitMQ 3.5.7 is as follows:


var ws = new WebSocket(‘ws://yourhostname:15674/stomp/websocket’);
var client = Stomp.over(ws);

Pipeline Shutdowns, Windows Versions, and dystopias

Thursday, May 13th, 2021

So, I’ve become sufficiently cynical to suspect that the actual running of the pipeline recently shut down by ransomware was done by industrial controllers, and the operators shut it down because they’re very conservative and they hoped they could make the Biden administration et al look bad. IT’s difficult to know, although I do hope this will push massive EV adoption. It would be nice if in their attempt to hold a gun to our head Big Oil committed suicide instead.

What I do know is that the hack occured becuase Microsoft abandons old windows versions. Now, this should be illegal – similar to how car manufacturers are required to provide repair parts for any mass produced automobile, Microsoft should be forced to release the source code for any operating system they abandon so volunteers can continue to maintain it. Linux proves that open-source software is more stable and secure than closed-source anyway.

Now, many people would say “No, you should be forced to regularly “upgrade” (in the case of win 10, downgrade) so Microsoft can continue making a profit. I don’t understand why these people want to live in a dystopia. Being forced to adapt to a change when you’re busy doing something else is clearly dystopian, and there’s also almost no chance that all the makers of (perfectly functional, useful, sometimes very complex and expensive) computer-interfaced hardware are going to manage to get drivers out for each new version Microsoft chooses to create.

Someone was trying to convince me we should nationalize Facebook because they’re upset Trump got kicked off it. No, that’s a horrible idea – my final argument that I would describe as a crushing blow was to ask if we should nationalize all communication infrastructure – should Fox News be nationalized? How is this different from Ganz Deutschland hört den Furher im Volksempfanger? No, I don’t think so. But we probably do need to have greater government oversight of Microsoft given the position operating systems play in our world – and as I said, they should be *forced* – if they want to stay in business in the USA – to release the source code of anything they abandon so it can continue to be maintained.

Let’s *try* to aim for *less* of a dystopia rather than more?

Side note – being forced to ride the upgrade train may be another example of how capitalism encourages us to make really bad decisions. It raises GDP, and our government seems to think a perpetually climbing GDP is a good thing, but it reduces effectiveness and wastes man-hours – it wastes real world resources to make paper ones. Sounds like another great example of the tool using us instead of us using the tool!

A possible alternative to ‘S mode’

Friday, April 30th, 2021

So, I had a interesting thought about a possible use for the blockchain. One thing it could be used for would be store known good signatures for applications – in this particular case, each time someone chose to run a application, you would look up the most recent block with that signature on it and you’d also run some hashes. As more and more hashes got run, the signature would become associated with a block starting with more and more zeros – the idea here is instead of letting Microsoft push a list of signatures as good (and after all, why should we trust them? They gave us windows 10, not to mention a long list of other stinkers) the group at large would decide which signatures were trustworthy. The idea here is that a attacker ideally would not be able to get a large enough bank of computers to do enough hashing to ‘legitimize’ a signature – you could also add things like a restriction of how many hashes per IP address per day could be registered etc.

I would like for us to have some way of knowing which binaries we could trust, I just don’t want to have to trust vendors we already know we can’t trust (i.e. Microsoft) for those signatures.

Another thought that came to me is how much better the world’s software would be if every ten years (say) everyone was *required* to release their source code and then anyone could develop it further. We’d end up with competing companies developing operating systems that ineroperated – it’s good that we have competing companies writing operating systems but it’s less than ideal that they can’t all run the same binaries (for example)

When to class / when to table

Sunday, January 3rd, 2016

So, there’s a related issue in database design and in object oriented programming, and it surrounds the question of when do I break this type of data off into a new table / new class?

Fully normalized data is a pain in the ass to work with. You have to join to find anything you care about, and there’s a performance cost to doing joins, especially outer joins. On the other paw, fully denormalized data is also a pain in the ass to work with. It can be very expensive to search that enormous haystack for that tiny needle, ALTER TABLEs take forever to run, etc.

In the programming world, if you create too many object classes, it’s a royal pain in the ass to find anything, your executable size is going to go up, and unless you do a very good job of inheretince you’re going to be doing cut & paste coding every time you add a good feature. On the other paw, if you create too few object classes, you’re going to find they get large and cumbersome as you have to add many methods to them for the varying sorts of data they’re carrying. Again, maintainability goes down, readability goes down.

So, how do you decide when it’s time to tack on a table or a class? I don’t really know how I make this decision – there’s some sort of intuitive leap that happens inside my mind that says ‘now would be a good time for another table / another object’. Sometimes there are clear data bounderies – a map coordinate probably doesn’t belong in the same table as a phone number, because it’s a very different type of data. Sometimes external APIs suggest a path, because of the way their interfaces are defined. And so forth.

I don’t have a good answer to write down here yet. I’m still thinking about this. But if anyone wants to comment, I’d be happy to hear your thoughts on the matter. (I think I have about 3 readers at this point, although my web traffic statistics would suggest that’s not correct)

How to write really good code

Friday, January 1st, 2016

1) Test *every single line*. I generally execute whatever I’m writing about once every 2-3 lines of code, once I’ve got the skeleton up. If you can’t do this quickly, change your workflow so you can.

2) Use human-language function names, variable names, method names, and class names. If a loop won’t fit on a standard IDE screen, use a human language iterator name instead of i.

3) If you find yourself cutting and pasting code more than once, use a method or a function.

4) If you’re not sure exactly how something is going to play out (like a regular expression, library system call, etc) create a very small program that only tests the way you are using it. This will encourage you to test out the possibilities involved more thoroughly, and once you get used to doing it it can be a very fast thing to do.

5) In #4, deliberately create bad data. Pass in empty strings, negative numbers, nulls, strings with SQL injection in them, strings that are too long, email addresses with no @ sign, and the like.

6) If you have a try {} catch {} – make sure you do something useful in the catch. If you need to break this rule (and occasionally you will) write a very descriptive comment as to why.

7) Know when you’re not in the headspace to code. Don’t try to program when you’re not capable of simultaneously seeing things as black and white and as shades of grey. Only you will know which emotions and thoughts make you write bad code – but in general, if you’re not in the place to program, don’t try. The rest of the team thanks you. Coding is the very essence of explaining rational thought about a subject in very very small steps, so if you’re not thinking rationally, you’re not going to write good code.

8) If you’re working on a very big project (20k+ lines), try to do all your developing in little testbed programs (as in #4) until you’ve got it working completely correctly. It is much faster to build and run small programs, and you also stand a much better chance of not stepping on someone else’s work

9) Use source code control. Check in early and often.

10) If you have a group of related data (for example, information about a customer), use a class. Even if it’s just carrying data – later you may find reasons to add methods to it. There’s a fine line to be walked here, however. You don’t want to use a class for the customer’s phone number’s format string. Usually.

11) Once you know and understand how to write code, you will see that a lot of the things your teachers tell you are basic rules are meant to be broken, occasionally. When you do break them, however, comment on which one you broke and why.

12) Build quality stuff. You never know when you will have to maintain it.

13) Refactor and rewrite. You will often get much better results the second and third time you write the same function. I actually prefer to write most things in a prototyping language (php, perl) before writing them in a compiled binary language, and I think switching languages also helps me write better code.

14) I generally write out psuedocode in human-readable language (english, in my case) before I start programming. This encourages me as a developer to think through what I’m trying to do before I start thinking about breaking it down into if/then/else

15) Every function should have a sane default path through it. switch() is a very powerful and useful tool because it encourages this. Sometimes the sane default thing to do is throw a exception.

16) For every variable that comes from ‘the outside world’ (a human out there on the net, a A/D converter, etc) make sure your code can cleanly handle completely unexpected values. What would happen if there were special characters? If it’s a signed type, did you handle negative? If it’s a nullable type, do you handle null?

17) While you’re doing #1, notice where the ‘pain points’ are. Use a profiler, or just capture high resolution timestamps. Figure out what ran slow and how you can make it run faster. This can be a fine art – for example, knowing which types of data sort will run better on the database engine and which will run better natively in your code takes quite some time to master.

18) When refactoring – if the source code is getting shorter, you’re doing it right.

19) Beware of excess convolution. Occasionally you will find you have done something silly like failed to initialize a useful variable set early in the process and instead calculated the value for that variable all over a set of nested function calls. If it feels confusing reading it, you probably need to rethink your approach.

20) Above all, have fun. Building really high quality things can be a great joy, if you let it. Remember to keep a positive attitude, and always work on having more patience. If you find yourself getting angry, you are probably not thinking rationally, see #7.

21) Remember, *nothing is set in stone*. One of the joys of programming in this era is you can go back and change your mistakes.

Perl arg parser

Monday, June 10th, 2013


I use this a lot when writing a simple perl script that I want to take args like –flag and –database=this and –comment=”This is a comment with spaces”

while($arg = shift) {

if(($s1,$s2) = $arg =~ /–(.*)=(.*)/) {
$l1 = lc $s1;
$s2 = $a if(($a) = $s2 =~ /^\”(.*)\”$/);
$arg{$l1} = $s2;
} elsif(($s1) = $arg =~ /–(.*)/) {
$l1 = lc $s1;
$arg{$l1} = 1;
}
}

Stick it in the top of the script, and you can then just use

if($arg{‘flag’}) {

}

$comment = $arg{‘comment’};

and so on and so forth.

Monday, January 23rd, 2006

1) I’ve updated my resume for those of you who care about such things. It’s at http://www.sheer.us/resume/SheerResume-ascii-wa.txt

2) Below please find a bootloader for a Atmel AVR AtMega8 which accepts a binhex file uploaded via windows terminal (or however else you would like). I’m releasing this code to the public domain at this point. Feel free to do whatever you like with it, or not, as appropriate. It could probably easily be modified for any AVR CPU

start_bld:
cli
ldi ZL, LOW(RAMEND)
ldi ZH, HIGH(RAMEND)
out SPL, ZL
out SPH, ZH ; set up the stack

rcall init_bld ; set up some hardware stuff
rcall idle_timer2_bld ; start timer2 ticking
rcall set_system_clock_bld ; setup the system clock for 7.2738Mhz

; check and see if there is a serial console present

sbis RS232_INVALID_IN_PORT, RS232_INVALID
rjmp bld_do_boot ; if no console, boot

ldi uart_char, XON ; send welcome banner
rcall uart_put_char_bld
ldi uart_char, ‘B’
rcall uart_put_char_bld
ldi uart_char, ‘l’
rcall uart_put_char_bld
ldi uart_char, ‘d’
rcall uart_put_char_bld
ldi uart_char, ‘>’
rcall uart_put_char_bld

rcall uart_get_char_bld_to ; get a char, or timeout and fall through
brts bld_do_boot
cpi uart_char, ‘B’ ; if ‘B’, then boot right now
breq bld_do_boot
cpi uart_char, ‘U’ ; if ‘U’, then go into upload mode
breq bld_do_upload ; todo: authentication

bld_do_boot:
jmp ivec_reset

; ‘stubbies’ used to make short relative jumps work okay

bld_do_upload_crc_special1:
rjmp bld_do_upload_crc_special

bld_do_flush1:
rcall bld_do_flush
rjmp bld_do_upload

bld_do_upload_err1:
rjmp bld_do_upload_err

; ******* Upload routine. Decodes lines of Intel Hex, writes them to the flash
; displays a error for bad lines

bld_do_booty:
rcall bld_do_flush
rjmp bld_do_boot

bld_do_upload:
; for now, fetch a line, check its checksum, report back good or bad, wash, rinse, repeat
rcall crlf_bld
ldi ZL, LOW(STRING_SCRATCH)
ldi ZH, HIGH(STRING_SCRATCH)

rcall uart_get_string_bld
ldi uart_char, XOFF ; send XOFF in case this
rcall uart_put_char_t_bld ; takes a while
rcall crlf_bld ; debugging
ldi ZL, LOW(STRING_SCRATCH)
ldi ZH, HIGH(STRING_SCRATCH)

clr XL
clr sample_cnt

ld uart_char, Z
cpi uart_char, ‘:’
breq bld_do_upload_ok
cpi uart_char, ‘F’
breq bld_do_flush1
cpi uart_char, ‘B’
breq bld_do_booty
cpi uart_char, CR
breq bld_do_upload
cpi uart_char, LF
breq bld_do_upload
rjmp bld_do_upload_err1
bld_do_upload_ok:
rcall ascii_to_bin_hex_bld ; convert first 4 bytes of input
; (should be length and high addr)

sts LINE_LEN, TempH ; save length in RAM
mov Temp2, TempH ; store byte count in temp register

sub XL, TempH
sub XL, Temp ; compute checksum

sts LINE_ADDR_H, Temp ; store high byte of address

rcall ascii_to_bin_hex_bld ; convert second 4 bytes of input

sts LINE_ADDR_L, TempH ; store low byte of address
sts LINE_TYPE, Temp ; store line type

sub XL, TempH ; compute checksum
sub XL, Temp

; fetch data, store in line

; hopefully data is even, but no guarentee

ldi YL, LOW(LINE)
ldi YH, HIGH(LINE)

cpi Temp2, 0
breq bld_do_upload ; if zero length record, skip

dec Temp2 ; LENGTH is +1, from dec standpoint

bld_do_upload_loop:
rcall ascii_to_bin_hex_bld ; translate ascii to binary

st Y+, TempH ; store bytes (high)
st Y+, Temp ; store bytes
sub XL, TempH ; compute checksum
sub XL, Temp

dec Temp2 ; LEN was given in bytes
breq bld_do_upload_crc_special1 ; special case: odd number of bytes
dec Temp2 ; but we do words so need 2 decs
brne bld_do_upload_loop ; go around again?

rcall ascii_to_bin_hex_bld ; grab CRC
sts LINE_CHECK, Temp ; store CRC
bld_do_crc_check:

lds TempH, LINE_TYPE

; ldi uart_char, ‘0’
; add uart_char, TempH
; rcall uart_put_char_bld

cpi TempH, LINETYPE_HDR
breq bld_do_upload

cp Temp, XL ; compare CRC to stored
brne bld_do_upload_err1 ; if it doesnt’ match, err

; matches, so program part

ldi YL, LOW(LINE) ; use Y ptr to access
ldi YH, HIGH(LINE) ; stored data for this line
lds Temp2, LINE_LEN ; Temp3 contains countdown
lds ZL, LINE_ADDR_L ; Z ptr is address in flash
lds ZH, LINE_ADDR_H
ldi XL, LOW(BOOTLOAD_START*2) ; X ptr is max flash addr to write
ldi XH, HIGH(BOOTLOAD_START*2) ; keeps us from writing bootloader
; which would put is in NWRW state
; and be bad

bld_do_program_loop:
cp XL, ZL ; check to see if we’re
cpc XH, ZH ; outside of the bootloader
brlo bld_do_program_loop_end ; do not program bootloader
; even if it is in file
mov TempH, ZH ; grab the page
mov Temp, ZL ;
andi Temp, 0xC0 ; skip off the byte address
; leaving only the page address

lds Temp3, LAST_PAGE_L ; compare against
cp Temp, Temp3 ; the last page that
lds Temp3, LAST_PAGE_H ; we used and
cpc TempH, Temp3 ; if it’s different
breq bld_do_program_skip_write ; then we need to write that page

; if we get here, then we must
push ZL ; preserve Z
push ZH

lds ZL, LAST_PAGE_L ; restore previous Z (page we
lds ZH, LAST_PAGE_H ; want to write)

rcall wait_spm_bld ; wait for SPM to clear

ldi Temp, (1<=? Then non-digit char, end

ascii_to_bin_hex_cont_bld:

adiw ZH:ZL, 1
movw mp16uH:mp16uL, YH:YL

ldi mc16uL, 16 ; load 16
clr mc16uh ; into multiplier

rcall mpy16u_bld ; and multiply

add m16u0, XH ; Add current value to stack
clr XH
adc m16u1, XH ; carry as needed

movw YH:YL, m16u1:m16u0

dec XL ; This keeps us from
brne ascii_to_bin_hex_loop_bld

ascii_to_bin_hex_end_bld:
movw TempH:Temp, YH:YL
pop YH
pop YL
pop Temp2
pop XL
pop XH
ret

uart_put_string_bld:
; put a null-terminated string to the uart
; Z should be pointing to the beginning of the string in RAM
clr uart_char
st Z, uart_char
ldi ZL, LOW(STRING_SCRATCH)
ldi ZH, HIGH(STRING_SCRATCH)

uart_put_string_loop_bld:
ld uart_char, Z+
cpi uart_char, 0
breq uart_put_string_done_bld
rcall uart_put_char_bld
rjmp uart_put_string_loop_bld

uart_put_string_done_bld:
ret

crlf_bld:
ldi uart_char, CR
rcall uart_put_char_bld
ldi uart_char, LF
rcall uart_put_char_bld
ret

uart_put_char_t_bld:
sbis RS232_INVALID_IN_PORT, RS232_INVALID
rjmp uart_put_char_t_done_bld

push Temp
in Temp, UCSRA
sbr Temp, (1<