Martin's Blog

Electronics, embedded firmware and software development from the perspective of 30 years in the industry.

Unit Testing Embedded C: Off-Target with CppUTest on Windows

The reasons for having unit tests in your projects are well-known and accepted; I'm not going to rehash them here. Whether you follow the school of thought that says you must write the tests first or your tests are written to prevent regressions and confirm that the implementation matches the design, you're going to need some unit tests. What I'm trying to do with unit tests is checking that complex logic matches the requirements, but I'm not necessarily interested in driver-level code or hardware-specific tests because the idea is to run them off-target. There needs to be as little friction as possible to you running the tests so that they get run frequently during the development process. Making them run as part of the build process means they don't get forgotten, but then they need to run fast to not…

Continue reading...

Building Embedded C Applications on Windows with GCC, CMake and Ninja

Most embedded C developers start writing their code on their microcontroller manufacturer's provided IDE - STM32CubeIDE, MPLAB X, TI Code Composer, NXP MCUXpresso, Segger Embedded Studio, Keil uVision, etc. The debugger support, peripheral setup tools and project structure support make this the right way to go, but at some point you should realise that these are not the best editors on the market and waiting for chip programming times makes your debugging cycle is slow. Although the manufacturer's IDE can be very capable, leveraging the power of Eclipse or NetBeans, there are many features of other editors like Visual Studio Code which make it preferable once your work moves away from the hardware-specific or register level debugging phases. VS Code is so much more customisable with themes, extendable with the extension marketplace and powerful with multi-pane, multi-window editing, as well…

Continue reading...

Using Finite State Machines to Implement Modal Applications

The ability to trace requirements through to implementation is an important property of commercial software development. As we know from the last 24 years of Agile, it's very rare to be able to obtain a complete, consistent and correct set of requirements at the start of the project, in practice they have to be continually refined during development. One of the common failings is to think only in terms of positive requirements - everything the product must do; and to forget the negative requirements - everything the product must not do. Very closely related is the problem arising from only specifying part of the logic, the default or happy path e.g. "when the button is pressed ..." and forgetting to specify the other part e.g. "when the button is released ...". It's not always obvious what the product should do…

Continue reading...

Countdown Timer for Children's Games: Firmware Design

In the first of these four blog posts on the firmware for the countdown timer, we'll look at the firmware layer design, the user interface functions and power consumption. The bargraph LEDs, buttons and switches are just GPIOs driven through my hardware independent driver layer, but there's more of interest in the seven segment display driver and speaker driver. Since there's no such peripheral as a seven segment display driver, at least not on this micro, I've had to write one. Driving the speaker with PWM proved slightly more difficult than you might expect, and there's some niceties around the sound that I wanted to include. We can't avoid main.c being generated by STM32CubeIDE and directly accessing the HAL, and it's the best place for the Wake pin callback, but we don't have to fall into the trap of putting…

Continue reading...

Countdown Timer for Children's Games: Hardware Design

The idea for this project was a simple countdown timer to be used by children for various games and activities where the user interface was designed to be as simple as possible; the display was clear from across the room and provided a sense of urgency, with a clear notification when the time was up. I started from the need for a large bright display, which meant using the largest economically available 7-segment LED modules. Starting a timer should be as simple as pressing a single button with a fixed function, so there is no time adjustment (up/down) facility which can be fiddly and non-obvious to use. Those often require long presses to get into a fast increment mode and are not consistent in how they accelerate. Choosing the time periods at the start of the project meant that the…

Continue reading...

Comment Driven Development for low-level design before coding

When trying to write code samples in front of someone else, for example during an interview, it's a good idea to start by writing down the steps required before converting those to code. Instead of writing them down just as a list, format them as comments with blank lines in between to make filling out the code easier. int main(void) { // fizz buzz example: // test integers in range 0 to 100 // print fizzbuzz if divisible by 3 and 5 // print fizz if divisible by 3 only // print buzz if divisible by 5 only // if none of the above conditions, just print the number } It's much easier to debug the algorithm or design by rearranging and changing those comment lines than by changing the code once you're committed to all the details - variable…

Continue reading...

The Case of the Field Problem

Picking up someone else's design to get it into production is a common enough situation and yet there are always interesting problems to be solved. These can get particularly challenging if that previous engineer has left the company and was the only one who really knew how the product worked. In this case, not only was it a new product, it was the first product of a new range using a new processor and new communications protocol, which we were going to develop into many more variants. So it was inevitable that there would be some bugs found by the first customers. Of course the product worked fine on the bench - it was when multiple products were wired together in the field that the bug showed up. Although as a product manufacturer we specified how the field wiring was…

Continue reading...

Getting to ping on STM32H743 with LWIP

Given that the promise of STM32CubeIDE is that adding functionality should be as easy as clicking in checkboxes, you'd think it would be easy to set up Ethernet on one of STM's own Nucleo boards which is designed for it, and to get it responding to ping on your internal network at a fixed IP address within minutes. If so, you've been misled by the way that simpler interfaces such as UART, SPI, I2C, and GPIO are easily configured with STM32CubeIDE/CubeMX, especially if you don't need to have them working through DMA. Because of the high speed nature of Ethernet, it is essential to use DMA and to get the caching set up right, and until you do, it doesn't work at all. Unlike UART, SPI, I2C or CAN, you can't just start with the simpler case of transmit-only to…

Continue reading...

Design of a processor and board independent driver layer

Reusability is an idea often touted in software, and embedded projects are no exception. In fact, the reasons for needing re-usability or ease of porting are often more pertinent to embedded projects even though the initial use-case doesn't call for them, and speed to market is usually business-critical. Why would the processor (or microcontroller) change after it has been designed-in? After all, the hardware designer has to make lots of decisions which are tied to that specific processor in that specific package, so it would be a lot of work for them to change it. Timescales for embedded projects often require the code to be in progress whilst the hardware is being finalised, PCB laid out and prototypes produced. If we can't start the driver layers until the prototypes are available, then it becomes risky to work on the aspects…

Continue reading...

How to harness the power of generated code in STM32CubeIDE with your custom code

Code generation from ioc STM32CubeIDE is a powerful piece of software, including code generation from a GUI formerly known as CubeMX, a code editing environment and a full debugger. The code generation feature should not be dismissed as a beginner level gimmick because it can be used within a professional environment, saving a huge effort compared to doing that work yourself, when you know how to keep it under control. If you're not aware of how to keep the code generator under control, you could lose code, be unable to get your code where you need it in the files, and feel restricted by it's imposed code structure. The CubeMX part of STM32CubeIDE can be used as a standalone application or integrated into the IDE and uses the [project name].ioc file to store the configuration of the peripherals, drivers and…

Continue reading...

Repairing a Panasonic DMR-EX77 PVR

After nearly 10 years of continuous operation, my Panasonic DMR-EX77 PVR died. The display went out and it didn't respond to the remote control. Sometimes this type of failure is just a fuse which has been stressed too many times by the inrush current produced when charging large capacitors in the power supply, but not this time. It was immediately obvious that the electrolytic capacitors had failed. I could see their bulging tops which are designed to blow out in the event of failure. All electrolytic capacitors have an expected lifetime which is mainly due to the wet electrolyte drying out at which point the capacitance drops and the equivalent series resistance goes up. It seems to be a common problem with these PVRs. On this product, the capacitors which needed replacing were identified as C1401, C1402, C4056 & C1557.

Continue reading...

An Unusual and Fast Bit Reverse Routine

A function to reverse the order of bits in a byte makes for a good interview question. The candidate has to think about loops, shifting and masking as well as the mundane but important issues of function and variable naming, data types, spacing and comments. As opposed to those "gotcha" questions apparently beloved by the tech giants where you have to know some trick, this can be worked through methodically. Once there is a solution on the table, there is an opportunity to talk about optimization for speed and/or space. There are lots of ways to approach this problem, but I suspect that many will take this simple idea of testing each bit and setting the LSB of the output in a loop which shifts up the output and mask one place each time. //bit reverse eg 0x80 return x01…

Continue reading...

Unit Testing Embedded C: On-Target with minunit and Off-Target with MS Test

Generally, the advice on unit testing in embedded environments is to run your tests on the PC host rather than on the target device. Whilst I agree that this is the most productive arrangement, there are a variety of reasons for needing to test on the target which can be convincing in certain situation. The technique described here allows for both. Mike Long in his GOTO 2015 presentation Continuous Delivery for Embedded Systems says "Test on your host because that's fast - it's a really fast way to develop. But also test on the target because behaviour can change in different ways, different compilers, different hardware..." Niall Cooling in his talk at the EmbeddedOnlineConference 2020 "How agile is changing the face of embedded software development" says (at 46m) on the gap between testing on the host and the target Things…

Continue reading...

Answering My Own Interview Question On Integer Maths In C

I've been using this interview question for the last 20 years to test embedded C engineers: Given the formula for Fahrenheit as 9 * C + 32 = F - 5 Write a function to convert unsigned char tempInC to unsigned char tempInF (ie. All values are bytes, including intermediate results). The processor has no floating point library. Recently I was intrigued to find that a very similar problem was posed by professor James M. Conrad at the University of North Carolina at Charlotte at this point in his lecture on Embedded Systems: Software Testing. The responses I used to get were similar to what the students gave in that video. Whilst some candidates would think this was a maths problem that needed rearranging to solve for tempInC, others thought that I just wanted them to write the formula in…

Continue reading...

Using and Misusing CRCs

CRCs are used for error detection in communication systems and storage systems. They have a combination of several advantageous properties whilst only requiring a short FCS, but they do have their limitations. If you require error correction as well as detection then you have to look at a different class of algorithms and will have to add much more redundancy to the codeword. The rest of this post is about message systems, where if an error is detected, the link layer of the protocol will take various actions such as discarding the message, sending a NACK, requesting a retry, waiting for retry until a timeout occurs etc. Another use of CRCs is for protecting data in memory, where similar considerations apply but the corruption possibilities may be different so you have to consider if the single random bit-flips model is…

Continue reading...

Choosing an Optimal CRC Polynomial

Most of the time engineers just have to implement communications protocols that are given to them: industry standards, decided by committees or established by the dominant players. But surprisingly often there is the opportunity to create a new protocol, either for proprietary internal use or as part of inventing a new standard for the industry, and in those cases we have to choose a CRC polynomial. Although the process sounds complicated, in many cases it can be quite simple. But first we must make sure we don't fall into one of the common pitfalls which leads to sub-optimal performance. Be wary of the many excuses for using a standard CRC Before you go ahead with a standard polynomial know that it is not the only choice and may well not be the best choice. What you are doing by choosing…

Continue reading...

You Are Probably Using A Sub-Optimal CRC

The designers of serial protocols like USB, Ethernet, CAN, or anything using "CRC-8" or "CRC-16 CCITT" did not have access to information on which CRC polynomials are the best for their bit-size and application, so were chosen on what seemed to be reasonable grounds but are now known to be sub-optimal. It is not necessarily that better polynomials were unknown in academic research but that the information had not reached an industrial design audience. In fact, it was widely believed that the performance of the polynomials was similar enough that you could just randomly pick one from a list in a book and it would be fine for your application. Koopman said CRCs have been around for a really long time. You would think that after all these years, the best CRC is a well solved problem. Unfortunately, it isn't…

Continue reading...

Clearing Up CRC Terminology and Representations of Polynomials

In the first post of this series on CRCs, I'm just going to clarify the terminology used. I am not going to cover the maths of how CRCs work in these posts, which can get surprisingly complex for what appears to be a set of simple bitwise manipulations and instead defer to Ben Eater's excellent CRC tutorial on YouTube. Small correction to the video, as noticed by commenter David W Smith, the length shown in Prof. Koopman's tables are in bits not bytes. They are for the dataword i.e. not including the FCS. I'm going to follow Prof. Koopman in his terminology Code Word is the whole message, with the payload being the dataword. Note that in this definition, any header is included in the Data Word. The Frame Check Sequence is the addition to the payload which adds redundancy…

Continue reading...

Hitting the Precision Limit of Excel; or 15 Digits Should be Enough for Everyone

Excel is a great all purpose tool, used by maybe 7% of the world's population. From shopping lists to budgets, Gantt charts and calendars to circuit simulators and digital music workstations, it can do it all. It is so good at so many things and so universally available to businesses that in many cases the biggest competition for software startups is not other specialized software solving the same problems but Excel. When it comes to using Excel for engineering tasks, there are lots of known pitfalls. Treating values as dates, or strings which are supposed to be hex like "51E67" as scientific format is one big category of pitfalls. Another is that although the probability of an error in any one cell is small, when you have a high number of cells all dependent on each other, the probability of…

Continue reading...

My All-Digital Instruments Electronics Lab

I've been building up this set of equipment on my bench at home over the last few months, with some older kit reused. It's the minimum needed to do embedded development and I don't even have a bench power supply yet. I can get away without one since the dev kits are USB powered, but when I need one I have my eye on the Gophert NPS-1601 From top left to bottom right 1280 x 1024 @ 60 Hz VGA and DVI inputs, USB hub with 2 downstream USB-A. Was £360 in 2003. 13" 1920 x 1080 @ 60 Hz matte non-touch display Intel i5-5200 CPU @ 2.20GHz (Broadwell-U, 14nm, 2 cores, 4 threads) 8 GB DDR3 RAM, 256 GB SSD Liteon L8H-256V2G-11M.2 Intel HD Graphics 5500 Windows 10 Home USB3 Type A x2, Mini Display Port, 3.5mm phones/mic, SD…

Continue reading...

Porting NovelBits' BLE Central Lightbulb controller to nRF51 & SDK version 12

Having got the BLE Lightbulb peripheral example working as I wanted it to on the nRF52 development kit (PCA10040), the next step was to get my other dev kit to be the controller for it, in place of the smartphone app. NovelBits helpfully provides all the code for this on the page How to build the simplest nRF52 BLE Central (Lightbulb use case) but it is targeted at the nRF52840 and SDK 15. I only had one nRF52 dev kit and one nRF51 dev kit. As I learned previously, the nRF51 is only supported by SDK version 12, so I had the job of porting the example code down from SDK version 15 and changing it over to the smaller, M0 based chip. At the same time, the Softdevice (BTLE stack) changes from s132 to s130. My plan was to…

Continue reading...

An Include File Manager for Segger Embedded Studio with Nordic SDK

SES Include File Manager A simple helper application for use with Segger Embedded Studio when working with the Nordic Semiconductor SDK. The application checks which paths exist and allows you to remove those that don’t, allows a search by filename to show which folder they are in, and allows conversion between relative and absolute paths for the include folders. (It does not search your SDK folder for include files to automatically add them to the include paths.) The Nordic SDK folder is structured so that many include files which are needed for a project are in different folders. All of the folder paths need to be added to the c_user_include_directories definition for the project to compile. It is time consuming to search for each include file that a compile will complain about being missing so that it’s path can be…

Continue reading...

Attempting to read and write emProject files as XML

Segger Embedded Studio project files appear to be XML formatted with a custom DOCTYPE. <!DOCTYPE CrossStudio_Project_File> <solution Name="ble_app_MA_lightbulb_pca10040_s132" target="8" version="2"> <project Name="ble_app_MA_lightbulb_pca10040_s132"> <configuration Name="Common" arm_architecture="v7EM" arm_core_type="Cortex-M4" arm_endian="Little" arm_fp_abi="Hard" arm_fpu_type="FPv4-SP-D16" arm_linker_heap_size="8192" arm_linker_process_stack_size="0" arm_linker_stack_size="8192" arm_linker_treat_warnings_as_errors="No" ... /> <configuration Name="Debug" c_preprocessor_definitions="DEBUG; DEBUG_NRF" gcc_optimization_level="None" /> </solution> Reading In VB.NET, Private xmlDoc As XmlDocument = New XmlDocument() xmlDoc.PreserveWhitespace = True xmlDoc.XmlResolver = Nothing xmlDoc.Load(filename) Once the XML is loaded, an attribute such as c_user_include_directories can be read using this syntax sIncludes = xmlDoc.SelectSingleNode("solution/project/configuration[@c_user_include_directories]").Attributes("c_user_include_directories").Value Writing However, writing out an this XML document object back to a file has a few problems. The DOCTYPE tag changes in that additional square brackets [] appear at the end due to a bug in the .NET framework, so you get <!DOCTYPE CrossStudio_Project_File []> which although is valid XML, causes SES to say that the file is not a valid project.

Continue reading...

Adding Brightness Control to the BLE Lightbulb Example

In the previous post on using a BLE peripheral example, the LED2 could only be controlled in terms of two states, On and Off. With my background of lighting controls, I wasn't satisfied that this could be called a BLE lightbulb project without at least brightness control. Since the example BLE code is already set up to send a byte as the BLE characteristic value, it should be easy to expand the example to brightness control in percentage terms using the byte in the range 0 to 100. The main addition to the previous project is the PWM software module which sets up and controls the internal PWM hardware peripheral on the nRF52832. It is better to use an existing software module which encodes all the knowledge necessary to set up the PWM peripheral rather than just accessing the registers directly…

Continue reading...

UUID Generator for Bluetooth Low Energy Products

If you are developing a BLE application with Nordic Semi's SDK, there is a need to generate a UUID for your custom services and characteristics, for example, NovelBits MIDI example. Mohammad Afaneh gives the rules for these UUIDs and suggests using a general purpose UUID generator followed by a manual check for clashes with the BT SIG reserved range. The Nordic SDK method of declaring these UUIDs requires them to be given as byte arrays in reverse order, with least significant byte first. Although this is not difficult to do manually, there is some possibility of error which would be difficult to detect without going through the full debug cycle of programming a device and reading back the UUIDs on a tool such as LightBlue or nRF Connect. I have automated the whole process in a simple Windows Form app…

Continue reading...

Getting a Simple On/Off BLE Peripheral Example To Work

I was getting a little frustrated with the Nordic examples and tutorials all being not quite ready for use. Not as badly frustrated as this guy but there always seemed to be some mismatch between what was required and what I was using, even when I chose the preferred tools. OK, I made a mistake assuming that I should start with the nRF51-DK because that is a smaller, simpler, cheaper chip. Although when you look into pricing, you find that nRF51's are not necessarily cheaper So I got myself onto the nRF52-DK so that I could use the latest SDK 16 and the Segger SES toolchain, which meets all the requirements in the Getting Starting guide. After going through that, I wanted to find a tutorial that was written from outside Nordic Semi so that it could be more objective about the tools.

Continue reading...

Comparison of 4.7" iPhones

Apple have just announced their latest 4.7" iPhone. Confusingly they are calling it the iPhone SE, even though they already had an iPhone SE which was a 4" screen. I'm looking at it as an upgrade to the iPhone 6s 128 GB from September 2015, so the comparison only covers that screen size. Most of the data in this chart is from Apple's comparison page. CPU and battery specs are from the relevant Wikipedia pages. The historical UK pricing at launch was obtained from the Guardian. DXO Mark and Geekbench scores are from their own sites. Bold text is used for improvements. Since the iPhone 8 did not launch with a 128 GB option, the choice would have been the 256 GB option at £849 so the iPhone SE (2nd gen) at 128GB at £469 looks like a good deal. Added confirmed…

Continue reading...

Eliminate Useless Timer Interrupts by Coalescing Timers

While learning about RTOSes, I came across the idea of Timer Coalescing which improves performance by eliminating unnecessary context switches. But there is no reason that this technique cannot be applied to bare metal firmware (without RTOS). To test out how well it works, I implemented it using a STM32F4 discovery board. I wanted to see the improvement factor in a typical use case, so I decided on running 8 software timers on a 1ms timer peripheral. The software timers count down to 0 then reload themselves. From previous experience, typical periods were chosen for these timers of 1000, 200, 125, 50, 18, 27, 40 and 600ms. (If they had a common factor of say 5ms, then it would make more sense to use that as the peripheral timer rate, but it restricts the flexibility for future changes.) TIM6 was…

Continue reading...

How your Obeng Project Type affects your Planning, Methodology and Leadership

Knowing what kind of project you are working on can help you work out which planning method and software methodology to apply, as well as what management strategy to use. Once you have categorised your project into one of these four types, you will improve your expectations about the timescale and velocity. Not knowing about these project types leads to confusion about the project direction and pace, which can be demoralising for staff and leads to misunderstanding by customers, management and other departments. The trend in the last 20 years has been to apply Agile methodologies to all projects, but this Feabhas video explains why that isn't always a good idea. (The click-baity title isn't what it first appears). I'd like to expand on the video by looking at the relationship between these four project types and the appropriate planning and execution…

Continue reading...

Trying to use nRF5 SDK 12.3.0 for nRF51 on a FreeRTOS project

Continuing from my Getting Started post, we now want to use the same method on a FreeRTOS example such as ble_app_hrs_freertos. When compiling, we get file include path problems, starting with nrf_ble_gatt.h. These can be fixed by adding the following entries into the Project - Options - Preprocessor - User Include Directories ../../../../../../components/ble/nrf_ble_gatt ../../../../../../components/libraries/sensorsim ../../../../../../external/freertos/source/include ../../../../../../external/freertos/portable/ARM/nrf51 ../../../../../../external/freertos/portable/CMSIS/nrf51 ../../../config/ble_app_hrs_freertos_pca10028_s130 But then we hit a problem in compiling 'port.c' - expected '(' before 'void' on line 92 port.c is in the Third Parties folder since it is a FreeRTOS file This is the compiler not accepting an asm void function, which isn't related to any changes I've made to get this to run but is a provided file. Let's see if it is any different in the later version of the SDK The source code is unchanged but the comments say that…

Continue reading...

Adding CMSIS Config Wizard to SES Projects

The CMSIS Config Wizard provides a GUI interface to many options which are otherwise tricky to set in sdk_config.h. To add it to your project, follow the instructions in this YouTube video, which I have summarised in text form below. First install Java. You might be lucky and already have Java installed, eg if you go to your Windows Settings - Apps & features and search for Java, if you see Java SE Development Kit then it is installed. File - Open Studio Folder - External Tools Configuration Paste in the following to replace the existing contents <tools> <!-- PC-lint - http://www.gimpel.com/html/pcl.htm --> <if host_os="win"> <item name="Tool.PClint"> <menu>&amp;PC-lint (Unit Check)</menu> <text>PC-lint (Unit Check)</text> <tip>Run a PC-lint unit checkout on the selected file or folder</tip> <key>Ctrl+L, Ctrl+P</key> <match>*.c;*.cpp</match> <message>Linting</message> <commands> &quot;$(LINTDIR)/lint-nt&quot; -v -incvar(__CW_ARM) -i$(LINTDIR)/lnt co-gcc.lnt $(DEFINES) $(INCLUDES) -D__GNUC__ -u -b +macros…

Continue reading...

Getting started with Nordic Semiconductor's nRF51 DK and Segger Embedded Studio

Choosing a Dev Kit The nRF51 is recent enough to be supported by a mature development environment and to have lots of others try it out before me. The Development Kit comes in a handy sized board which only needs micro USB for power and data, and has a built in SEGGER JLink debug chip, as well as 4 user buttons and LEDs, and all the usual ports. It uses the nRF51422 which is Cortex M0 based, so I thought it would be a good way to do some M0 development work. In comparison, the later nRF52 series are M4 based, more capable but more expensive. I decided I didn't need the feature of the nRF52/Cortex M4, which was my first mistake. Nordic's Getting Started Guide v1.3, which covers the nRF51 DK, recommends Segger SES as the preferred development enviroment…

Continue reading...

Improving frequency measurement performance by factor of three on STM32 by using DMA

This Youtube video by Controllers Tech shows how to use an STM32 to measure the frequency of an incoming rectangular wave using the input capture functionality of the timers. The code shown the video works but there are a few areas which could be improved, as I will now discuss. Then I make a performance improvement by using DMA instead of interrupts. The code is written using STM's HAL library which means that it does not have to handle the specific STM32's registers, which makes it more portable. However, HAL is still specific to the ARM and STM architecture, so you need to know what features are available in your internal peripherals to be able to write HAL function calls with the appropriate parameters. Initialising Global variables Controllers Tech declares a set of global variables at the top of main.c and initialises them…

Continue reading...

Replaying a captured 'scope trace using a Siglent DSO and FeelTech FY6900

When you are developing an embedded device, you often find yourself capturing an interesting signal with the 'scope that you would like to send back into your device. If you have invested in an Arb from the same family as your 'scope then this is as easy as moving a USB Flash drive from the 'scope to the Arb, but such Arbs are not the cheapest option out there. Since choosing the FeelTech FY6900 as my Arb, I found that it's software "DDS Signal PC Software" can import a list of points but the format is not the same as exported by the Siglent SDS 1104X-E. So I wrote a utility to convert from one to the other, and with some additional options. This is a utility for converting scope captures from a Siglent Digital Storage Oscilloscope into a format…

Continue reading...

Choosing a Signal Generator

A common problem in embedded firmware development is having to develop routines which read-in a given signal. Usually you have a sample device available which can produce the required signal on demand, but it is not always quick and simple to get this signal when you need it, and to get an exactly repeatable version of it. For example, if it is a sensor signal, then the signal will vary according to the sensed parameter (temperature, humidity, light) and will vary just due to noise so that it is difficult to get exactly the same signal twice. Even if you have the sample device and it can be made to produce the signal, it can be bulky, heavy or power consuming and so difficult to have on your desk along with your prototype hardware. Therefore there is often a need…

Continue reading...

Sampling a Pulse Stream Mid Bit When the Clock Frequency Varies

When faced with the task of reading in an asynchronous bit stream (i.e. one without a separate clock pulse line), the best solution is to use an onchip UART peripheral. However, there are many cases where it isn't possible to use a UART, for example: The micro has no UARTS, or the ones it has are already used. The pin can't be assigned to UART receive function - simpler micros have fixed pin functions; even in more complex micros not all pins can be mapped to any function. The base clock doesn't allow for the right UART clock rate with any of the possible divider options. The bit stream doesn't correspond to UART format, for example - more than 9 data bits, Manchester encoding, non-standard number of start and stop bits. The bit stream has a wide variation in pulse…

Continue reading...

Repairing a NAD 502 CD Player

My trusty NAD 502 CD Player, which I bought in 1996 from Richer Sounds, developed a fault a few months ago. The display went completely dark, so although it would play CDs perfectly, it was tricky to operate. Luckily it was not a failure of anything more complex than the backlight, which turns out to be a couple of wire-ended small capsule lamps. This CD player has a fantastic specification and had great reviews at the time, so I was not in a hurry to dump it for a newer model just for the sake of some tiny and cheap lamps in the display. This really is built-in obsolescence because any incandescent lamp will eventually burn out, and these are not even replaceable without soldering. I suppose it was a cheap option at the time, and maybe the design life…

Continue reading...

Choosing A 'Scope For Embedded Use

As an embedded engineer, I need to be able to see signals on the board under test in a reliable and trustworthy way. It is important to see a few signals on the same display to be able to measure time differences between them, so a multi channel oscilloscope is essential. Whilst it sounds like it would be a good idea to see as many signals as possible at once, this is only possible on a logic analyser, which reduces the analogue nature of the signals to a digital one. Logic analysers are great for multiple signals, once you are sure that the digital waveforms have the right analogue characteristics - high level, low level, rise time, fall times, ringing, spikes, noise, gitches on the edges. The logic analyser will hide all that from you and always show perfectly squared…

Continue reading...

Repairing an IKEA drawer unit

This had broken due to the weight of the items in the drawers causing the brown plastic runners to break. It's not that easy to find replacement runners, and in any case, they are likely to break again if they are used with this much weight - the unit is clearly designed for clothes, not paper files. It was clear that I needed to find a metal runner that could fit in the same slots to replace the plastic runners. Luckily, the slots in the drawers are a standard width and length: 17mm width and 350mm length, so these metal runners fit. They need securely fixing into the chipboard side panels, but an ordinary wood screw is not going to be able to take the weight. The pressure on the bits of chipboard just under the screws would be too…

Continue reading...

Why Can't You Change It? It's Software isn't it?

Everyone expects software to be soft. To be easily changeable. At least more easily changeable than hardware. But that is not always the case, sometimes it is easier to redesign the hardware than the software, but why and what do we mean when we say it is difficult to change software? Before the product has shipped, it should be easy to change both the hardware and the software as necessary to achieve the design. After the product has shipped, the hardware is fixed and you can only change the software. But there are often difficulties in changing software that mean it isn't as flexible as it might appear. What do we mean when we say it is difficult to change software? Let's start with what we don't mean. We don't mean that it's too much typing, or too many files,…

Continue reading...

Fast reading of Excel worksheets into a .NET program

Reading data from Excel into a C# or VB.NET program using Interop.Excel.dll can be very slow because each read operation goes through a slow path in Windows (about 50ms), so instead of looping through each Range or Cell object to read one cell at a time, it is much better to read the entire Range (multiple cells) of interest in one go, and then do the looping on an array inside the program, without having to pull data in from Excel on each iteration. First get the dimensions of the sheet you wish to process. Here is a handy function to do that: ''' <summary> ''' Gets dimensions of Excel worksheet, assuming the first used cell is at (1,1). ''' </summary> ''' <param name="w">Worksheet object</param> ''' <param name="numrows">Returns the number of rows found to be used in the sheet</param> '''…

Continue reading...

The Product Support Trap for Development Engineers

In all the companies I have worked, when the product development is finished it gets passed on to manufacturing and product support but the original developer retains ownership of the design. It's important that the product support department gets full training on how the product works, how to use it, how to diagnose problems in the field and on the bench, and what happens under misuse and failure conditions. But I have never seen a product support department really own the design to the extent that they could diagnose down to component level in the hardware or line of code in the software, which means that the last line of technical support comes back to the R & D engineer. Too often, that last line is perilously close to the first line, such as when the support team are understaffed…

Continue reading...

Welcome

Welcome to my blog, "Commented Out", where I tell stories of product development, finding bugs, solving electronics design problems and generally looking at embedded firmware development and deployment. I've gained experience across a few technologies in my career so far, but electronics and software is a fast growing field which can quickly leave you behind if you don't make an effort to keep up. So I am entering a period of retraining. I'm also going to be using this blog as a way of documenting my progress during my retraining period. I'll be learning a range of different technologies and keeping notes here which I hope will be helpful to others as they start out on the same path, or at least be something for me to look back on as I learn. In some posts, I'll cover subjects which are…

Continue reading...