Wednesday, March 1, 2017

Simple H-Bridge Tutorial

A little while ago I made a couple electronics videos on basic H-bridge design concepts. They're intended to be introductory, but unlike other introductory sources that focus on quick and dirty (and all too often incorrect or hazardous) implementations, these tutorials focus more on design thinking and avoidance of hazards.

Part 1: How NOT to Build an H-Bridge Motor Controller

This video looks at several popular H-bridge designs that don't work as advertised. We investigate why these designs are hazardous, and steer newbie roboticists away from common pitfalls that can damage your electronics, and even your health.

Part 2: How to build a proper H-bridge that probably won't catch fire

Now that you know how not to do it, we'll design a basic fully-functional H-bridge with BJT transistors from scratch. The video focuses on practical design thinking that applies to a wide variety of H-bridge designs.

Tuesday, October 18, 2016

Tips and misunderstood features that every programmer should know about HTML/CSS/JavaScript

This post is a compilation of tricks for web development. I'll continue to update the list as I come across new points. The focus will be on small facts about HTML, CSS, JavaScript that are largely misunderstood or waste time (especially the first time you encounter them), but I won't touch on helpful third party frameworks much.  To submit a fact (or correction) for this list, post it in the comments section or email me.

Bookmark this page and check back often for new tips all the time. Don't forget to follow me on Twitter.

HTML

  • For <!doctype html>, the doctype is case-insensitive. This is valid in all compliant HTML parsers, but is not correct in XML.
  • When using the <script> tag, specifying type="text/javascript" is optional. JavaScript is already the default programming language in all browsers.
  • In HTML5, the <head> tag is obsolete. Put your metas, scripts, titles, and so on directly in the <html> tag, but outside <body>.

JavaScript

  • If you're not sure whether you should use == or ===, just remember that " " == 0 is true, but " " === 0 is false. 
  • Also, true == 1, but true != 2.
  • To use a switch statement with conditions, do this:
    switch(true){
        case boolean_condition1:
            //Code
            break;
        case boolean_condition2:
            //Code
            break;
    }
    Or, just use if/else if statements.
  • The double tilde trick in JavaScript is frequently used to floor numbers (~~3.9 == 3). But never use it.
  • In JQuery, if you use the empty or remove functions, JavaScript's garbage collector will delete any references to event handlers for the deleted components. If you remove stuff that has JavaScript events attached using something like document.getElementById("foobar").innerHTML = "", you could leak memory.
  • If you want to transfer data from your server to JavaScript via your rendering engine, one possible hack is by writing data to a var, for instance:
    var value = {{myNumber}};
    var value = <?= echo myNumber ?>; 
    var value = @(ViewBag.myNumber);
    Or whatever... But if you're worried that the value might not exist on the server, use this instead: var value = Number("{{myNumber}}"); so that if the value doesn't exist, it won't crash the client side with an "expected value after =" error.
  • The return keyword breaks if the return value is on a separate line. Semicolons are optional and JavaScript can be lazy in unexpected ways.
  • You don't need jQuery to use css selectors to query elements in JavaScript. document.querySelectorAll() is an underrated built-in function that does nearly the same thing (though jQuery does add some nice features).

CSS

  • When positioning elements as absolute, the target will, by default, be positioned relative to the window, unless one of the target's parents (or ancestors) are positioned as anything except static. So if a container is positioned as relative, it's children can be positioned as absolute, and setting things like left: 0, etc. on the child will position it relative to the parent.
  • Browsers interpret decimal numbers in their own way. For instance, the current latest version of FireFox seems to ignore any "px" value with a decimal value. Chrome is inconsistent. Edge seems to be very robust, however. This is important to consider when setting style using JavaScript. If you're experiencing really weird style bugs with varying behaviors across browsers, and your web page uses dynamic styles, this is probably a good thing to keep in mind when you start debugging.
  • Percentages for vertical margins and paddings are relative to width, not height. 

Like I said, it's a work in progress. More to come.

Monday, September 19, 2016

Make node auto-restart on Windows

Whether it's recovering from an unexpected crash, or doing a quick reboot to update the server code, this four-line batch file is what you're looking for.

:start
node app.js
echo %date% %time% >> rebootlog.txt
goto :start

The third line is important here. Don't neglect proper logging or you might not realize there was any crash at all. After all, the point of this is to reduce downtime, not lazy error handling.

Happy coding.

Sunday, August 28, 2016

The double-tilde (~~x) technique in JavaScript - What it is, and why you should be careful about using it.

Watch



What is it?

The ~ (tilde) operator in JavaScript is the often-overlooked bit-wise not. For integers, it is the equivalent to running:

~x == -(x + 1)

So ~(10) will give you -11. There's another caveat to the ~ operator. It casts floating point numbers to integers by dropping everything after the decimal. So in the more general sense,

~x == -(Math.trunc(x) + 1)

Recall that Math.trunc() is kind of like Math.floor(), except the value (positive or negative) will always be rounded towards 0. The ~~ technique is a common trick you'll find a lot of developers using. Let's resolve it:

~~x = -(Math.trunc(-(Math.trunc(x) + 1)) + 1)
-(Math.trunc(-(Math.trunc(x)) - 1) + 1)
-(Math.trunc(-(Math.trunc(x))) + 1 - 1)
-(Math.trunc(-(Math.trunc(x))))
= --Math.trunc(x)
Math.trunc(x)

Essentially, ~~ is used as a short-hand hack for Math.trunc(). 

But you should probably never use it.

I'm pretty lazy so I use to use this a lot... until it got me in trouble. It turns out that ~~ doesn't work for really large numbers. For instance, when I run ~~1000000000000, the result is -727279968, so in this case not only did we lose a ton of precision, the answer actually has the wrong sign! So if you were expecting a positive number because the input was positive, this type of thing can really wreak havoc, like crashing your Node.js server or whatever.

But even if you understand the way that numbers work in JavaScript and only use the ~~ trick where appropriate, I would still contend that using this technique is detrimental in the same way as goto statements or the xor swap algorithm. It's esoteric, and prone to bugs. It is not beginner-friendly, doesn't come with documentation, and if accepted by convention could lead unknowing developers down the path to buggy code.

Alternative?

Instead of using ~~ just stick with Math.floor(). If you want a way to truncate decimals (flooring both positive and negative numbers towards 0), add this declaration at the top of your code:

if(!Math.trunc){
    Math.trunc = function(value){
        return Math.sign(value) * Math.floor(Math.abs(value));
    }
}

Note that Math.trunc() is already available in ECMAScript 6 compliant JavaScript engines (which is used by most modern browsers, but not all), and doesn't need to be added in those environments.


Tuesday, August 9, 2016

Add sleeps or yields to JavaScript loops with Sequencr.js

Add sleeps or yields to JavaScript loops with Sequencr.js

Ever wish JavaScript had a built-in sleep function to help you build loops for computationally difficult tasks without killing the browser? Yea, we all have. Obviously we can always cascade setTimeouts, but can get messy fairly quickly.

Recently, I published a JavaScript library, Sequencr.js, that's helped me with this problem. It's fairly simple, but so deceptively useful that I've found myself using it in tons of different projects. Check out the project page:


Enjoy!

Update

Sequencr.js is now  a fully functional promise library. It makes promises a lot easier to work with and adds some interesting design patterns like asynchronous promise-based iterators. 

Saturday, October 4, 2014

Adding Remote Logins to SQL Server 2012

This should be quite easy to do but it can also be a headache if you're doing it wrong and are lost like I've been the first few times I did it.

The task is creating a remote login for SQL Server 2012 so that can be accessed remotely. I'm not going to get into the details of setting up SQL Server for remote access because there are many other resources on that.

There's a very silly mistake that's easy to make when looking at all the available guides on how to create remote logins that no one ever talks about. According to most guides there should be a "logins" folder under the security folder. They're referring to the security folder on the server instance, not one of the database instances. Don't create a new user for the DB yet, create a new login for the server!

So to create a login by expanding server instance -> security and right click on logins. This will allow you to create a new remote login. Use SQL server authentication mode, which will allow you to type a username and password. The login can be added to a database using the user mappings tab. Don't forget to set up permissions under user mappings for each database, and be sure to choose the right default database or you'll get complaints whenever you try to log in remotely or make queries.

If you modify things in the securables tab you might get an error like this:


So don't do it.

Refresh the database(s) you chose as your mappings in the previous step and your user should be there under server instance -> databases -> your database -> security -> users.

Piece of cake!

Tuesday, September 16, 2014

Setting up multiple FTPs on IIS 8.0

530 valid hostname is expected

To set up multiple FTPs on IIS 8.0, make sure to remove virtual host-names from bindings and use unique ports for each connection for routing.

530 User cannot log in, home directory inaccessible

Let pathname be the location of your FTPs home directory. Open a command prompt as admin and type:

ICACLS "pathname" /Grant IUSR:R /T
ICACLS "pathname" /Grant IUSR:W /T