The Fourier transform maps a signal to its frequency spectrum, denoting exactly at which amplitude a given frequency appears in the signal. The underlying assumption is that any signal out there can be decomposed in to an infinite sum of trigonometric functions with varying amplitude, phase, and frequency. But what happens if one of the most basic functions, the cosine itself, is transformed?
Applying filters to signals is one of the most important applications of mathematics in signal processing. But with all the Fourier transforms, Convolutions, and various properties like causality, time-invariance, linearity… It can get confusing. In this post, I want to clarify the relationship between a filter, it’s impulse response and transfer function, and why applying a filter is the same as convoluting a transformed signal with an impulse response. Don’t worry, it will sound less intimidating in the end.
In this post, we will explore how Rust distinguishes between expressions and statements. Even though this distinction seems very theoretical, it has wide-ranging implications on the Rust language and (in my opinion) is a beautiful detail of Rust.
When learning about Rust for the first time, one is confronted with words like ‘double free’, ‘data race’, and ‘dangling pointer’. Without an understanding of these problems, the safety aspects of Rust are perhaps difficult to appreciate. However, Rust aims to appeal not only to systems programmers(where these kinds of problems are well-known), but developers from any background! It is perfectly fine to write high-level Rust code without knowing what a data race is (that is the freedom Rust grants) but understanding the underlying issue makes the compiler error messages more understandable.
Most Arduino users won’t ever need interrupts or even C++/OOP for that matter.
But for writing a nice object-oriented library or advancing your programming
skills, both are very interesting subjects. But they clash somewhat: an
interrupt is basically a global function that takes no arguments (not even
this) and returns no value, either. It is not called by the main
program like regular functions, but instead runs when it is triggered by an
external signal, like a pin logic voltage level change. This idea has no place
in an OOP (let alone functional!) world - what object does the function belong
to? It is global and cannot see or modify anything but static data, and the
fact that it does not take arguments makes it impossible to call this function
with method syntax. If this is confusing, don’t worry: in C++, a function knows
which object it belongs to by the implicit, invisible argument
it is still confusing, don’t worry - it doesn’t really matter. It just means
that interrupts and OOP do not mix well.
The Arduino toolchain is a good starting point. So many libraries, most of them fine quality, and the editor allows you to write incorrect C++ so you can have a simpler life…
In this article, I want to present a PID-based multi-purpose balance controller that runs on the Teensy 3.2 board using Arduino libraries. It can control PWM-based actuators like servos or LEDs and electronic speed controllers driving brushless motors. This control is based on an external signal like the output from an RC receiver, and the output of an inertial measurement unit.
Errors (not human errors, but literally error conditions) can happen very quickly even in simple Arduino projects. For example, an external library might sometimes fail to load data from memory due to unreliable hardware (like with the MPU6050). In this case, if you have a serial connection, you might see the error description printed there. But what if you have no serial connection because you are using your board without having a computer connected?
Sanglard explains how floating point numbers are generally displayed in modern
computers (using the
IEEE754 Norm). His alternative perspective using
buckets and offsets is brilliant and explains a fact that may be
overlooked when using the standard explanation: the accuracy of floating point
numbers declines with a factor of 2 by each bucket! That is because the same
‘amount’ of numbers is dispersed in any bucket, but the size of the bucket
doubles every time.
In this StackOverflow post, a question about the ‘Most productive Vim keyboard shortcut’ sparks a long discussion about Vim and productivity. In this answer, titled ‘Your problem with Vim is that you don’t grok vi.’ which is easily one of the most influential pieces of Vim documentation and intro material on the internet, user Jim Dennis takes the question apart and shows how Vim is not about shortcuts but about a language for manipulating text. If you read and understood this answer, you probably don’t need to read this post here, since it is just my personal take on the Vim philosophy.
Usually, we expect that negating a number yields a number which is of the same absolute value, but with a flipped sign. However, there is a curious behaviour in many programming languages where this property does not hold for one special case. You might have come across this if you (like me) tried to (mis)use a constant Integer.MIN_VALUE (or somesuch) to simulate something like negative infinity. For example, this could be useful in a min-max algorithm with alpha-beta pruning.
This is a simple Jekyll-powered blog. I intend this blog to be a log of interesting things I come across while programming, studying math, or attempting to make hardware do things.