Thursday, 18 June 2020

Developing Artificial Intelligence Applications using Python and TensorFlow course at the University of Oxford

I've been broadening my AI knowledge over the last few weeks by attending the "Developing Artificial Intelligence Applications using Python and TensorFlow" course at the University of Oxford. University of Oxford, Department for Continuing Education.

https://www.conted.ox.ac.uk/courses/developing-artificial-intelligence-applications-using-python-and-tensorflow.

Course Director is the very knowledgable Ajit Jaokar.

If any of you want to learn more about AI, I can't recommend the course highly enough.

I'm sure Ajit will be running more courses because this one was over subscribed so sign up ASAP.

#AI #artificialintelligence #machinelearning #universityofoxford #datascience

Sunday, 24 May 2020

A Simple Google Assistant On The Raspberry Pi

Here's a fun lockdown project that explains how to integrate a Google assistant on a Raspberry Pi : https://github.com/Numerix-DSP/GoogleAssistant .


Saturday, 16 May 2020

Timing DSP Code Running On ARM Cortex Architecture

A recent project reqired porting some DSP algorithms to the NXP LPC55S6x ARM Cortex-M33 based microcontroller.
It was necessary to benchmark the algorithms so I wrote the following code that utilizes the Cycle Count Register, which is part of the ARM Cortex-M Data Watchpoint and Trace (DWT) unit.

The code below includes macros for accessing the DWT and also calculates the overhead of calling the functions to read the timer register, before using the same functions to time some code.
This code has been compiled and tested on the NXP LPCXpresso55S69 Development Board but should run on any ARM device that includes the DWT module.

#include "fsl_debug_console.h"

// Timers
// DWT (Data Watchpoint and Trace) registers, only exists on ARM Cortex with a DWT unit
#define KIN1_DWT_CONTROL          (*((volatile uint32_t*)0xE0001000)) // DWT Control register
#define KIN1_DWT_CYCCNTENA_BIT      (1UL<<0) // CYCCNTENA bit in DWT_CONTROL register
#define KIN1_DWT_CYCCNT            (*((volatile uint32_t*)0xE0001004)) // DWT Cycle Counter register
#define KIN1_DEMCR                (*((volatile uint32_t*)0xE000EDFC)) // DEMCR: Debug Exception and Monitor Control Register
#define KIN1_TRCENA_BIT          (1UL<<24) // Trace enable bit in DEMCR register

#define KIN1_InitCycleCounter() KIN1_DEMCR |= KIN1_TRCENA_BIT     // TRCENA: Enable trace and debug block DEMCR (Debug Exception and Monitor Control Register
#define KIN1_ResetCycleCounter() KIN1_DWT_CYCCNT = 0          // Reset cycle counter
#define KIN1_EnableCycleCounter() KIN1_DWT_CONTROL |= KIN1_DWT_CYCCNTENA_BIT  // Enable cycle counter
#define KIN1_DisableCycleCounter()  KIN1_DWT_CONTROL &= ~KIN1_DWT_CYCCNTENA_BIT // Disable cycle counter
#define KIN1_GetCycleCounter()      KIN1_DWT_CYCCNT                             // Read cycle counter register


int main(void)
{
uint32_t start_time, end_time, overhead_time; // number of cycles

KIN1_InitCycleCounter(); // enable DWT hardware
KIN1_ResetCycleCounter(); // reset cycle counter
KIN1_EnableCycleCounter(); // start counting

start_time = KIN1_GetCycleCounter(); // get cycle counter
    __asm volatile ("nop");
    end_time = KIN1_GetCycleCounter(); // get cycle counter
    overhead_time = end_time - start_time;

PRINTF("Mutex example started.\r\n");

  start_time = KIN1_GetCycleCounter(); // get cycle counter
    __asm volatile ("nop");
    __asm volatile ("nop");
    end_time = KIN1_GetCycleCounter(); // get cycle counter
    printf ("Elapsed time = %d cycles\n", end_time - start_time - overhead_time);

    return(0);
}

Notes
There appears to be a +/- 1 cycle jitter on the results of any code timing instance. I have not got to the bottom of exactly why but regardless of the route cause, this is very accurate and definitely suitable for the vast majority of applications.

References





If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.
Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/

Monday, 27 April 2020

Python/Numpy : How Not To Generate A Sinusoidal Waveform

I was recently reviewing some Python/Numpy code that included a waveform generator. A simplified version of code looked like this :

x = np.linspace(0,2*np.pi-(2*np.pi/8),8)
np.sin(x)

This generates the following :

array([ 0.00000000e+00,  7.81831482e-01,  9.74927912e-01,  4.33883739e-01,
       -4.33883739e-01, -9.74927912e-01, -7.81831482e-01, -2.44929360e-16])

Which looks like a perfect single cycle of a sinusoid. Except it isn't !
On closer inspection, the last element in the array is, to all intents and purposes, 0, which means that this isn't a perfect single cycle of a sinusoid because that final sample is actually the first sample of the next cycle.

To generate a perfect single cycle of a sinusoid using linspace you need to account for where the last sample of the sinusoid should fall, if you were to plot it on a graph.

x = np.linspace(0,2*np.pi-(2*np.pi/8),8)
np.sin(x)

This generates the following array, which is spot on :

array([ 0.00000000e+00,  7.07106781e-01,  1.00000000e+00,  7.07106781e-01,
        1.22464680e-16, -7.07106781e-01, -1.00000000e+00, -7.07106781e-01])

In thinking about this problem, it occurred to me that this is not ideal and very likely to cause confusion becasue it is easy to forget the required modification. The main reason for the confusion is that standard Python generates and processes data from, for example, 0 to N-1 as shown in this simple Numpy example :

np.arange(8.)

Which yeilds :

array([0., 1., 2., 3., 4., 5., 6., 7.])

So returning to the original problem, a far safer way of generating the sinusoid is the following code :

x = np.arange(0., 2.*np.pi, 2.*np.pi/8.)
np.sin(x)
Which generates the following array :
array([ 0.00000000e+00,  7.07106781e-01,  1.00000000e+00,  7.07106781e-01,
        1.22464680e-16, -7.07106781e-01, -1.00000000e+00, -7.07106781e-01])

Now we have the first np.arrange() instruction to generate the time index and the second stage np.sin() to generate the sinudoid. This is clear, precise and unlikely to cause error.

Side note : of course, it would be entirely possibl to combine this into a single line instruction however I believe this causes other possibilities for error insertion.



Saturday, 25 April 2020

The Difference Between FFT Spectrum and Power Spectral Density

I always teach the difference between FFT Spectrum and Power Spectral Density on my DSP courses and many students find it confusing.

This applications note from Audio Precision summarizes the subject very neatly : The Difference Between FFT Spectrum and Power Spectral Density

Functions for calculating both the FFT Spectrum and Power Spectral Density are included in the SigLib DSP Library.

Saturday, 8 February 2020

VMWare Virtual Machines On Windows 10 - Disabling Device/Credential Guard - Solution

Not a DSP related post but something that caused me no end of unnecessary pain.

I use Virtual Machines a lot but they stopped working under Windows a while back with the following message :

"VMware Workstation and Device/Credential Guard are not compatible"

The VMWare URL pointed to a Microsoft webpage that was out of date with the newer version of Windows 10 I am using [Version 10.0.19041.21].

This helped greatly but, unfortunately, it is still out of date :
https://www.tenforums.com/tutorials/68913-enable-disable-device-guard-windows-10-a.html

Here is what I had to do but note, VMWare only started working after doing all three so the first two might not be necessary but it works now so I'm not going to make any changes ;-)

Control Panel | Programs And Features | Turn Windows Features On or Off | Untick the following :
Hyper-V
Virtual Machine Platform
Windows Hypervisor Platform


Search Windows for “Group Policy” open "Edit Group Policy" app and do :
Computer Configuration\Administrative Templates\System\Device Guard
Disable : Turn On Virtualization Based Security

Download dgreadiness from here : https://www.microsoft.com/en-us/download/details.aspx?id=53337 and do the following in an Administrator PowerShell :
.\DG_Readiness_Tool_v3.6.ps1 -Disable
Reboot.

Unfortunately, breaks Windows Subsystem For Linux :-(.
My current solution, to run WSL2, is to do the following in an Administrator PowerShell :
.\DG_Readiness_Tool_v3.6.ps1 -Enable
Reboot.

This is so bloody stupid, that I can't run a VM and WSL side-by-side.

I'll endeavour to keep this page updated when Microsoft change things, again.

PS I'm sure this is also necessary for VirtualBox but I haven't got a current Windows 10 hosted VirtualBox to test.

Wednesday, 4 December 2019

The Next Round Of The University Of Oxford, UK Digital Signal Processing Courses Take Place In July 2020

As part of the University Of Oxford Summer Engineering Program for Industry, the Digital Signal Processing courses are returning in June 2020. for the 28th year.

The courses are presented by experts from industry for Engineers in industry and over the last 27 years has trained many hundreds of Engineers, from all areas of Science and Engineering.

Here is a summary of the two courses.

Digital Signal Processing (Theory and Application) - Monday 6th to Wednesday 8th July 2020

https://www.conted.ox.ac.uk/courses/digital-signal-processing-theory-and-application
This course provides a good understanding of DSP principles and their implementation and equips the delegate to put the ideas into practice and/or to tackle more advanced aspects of DSP. 'Hands-on' laboratory sessions are interspersed with the lectures to illustrate the taught material and allow you to pursue your own areas of interest in DSP. The hands-on sessions use specially written software running on PCs.

Subjects include :

Theoretical Foundations
Digital Filtering
Fourier Transforms And Frequency Domain Processing
DSP Hardware And Programming
ASIC Implementation
Typical DSP Applications

Digital Signal Processing Implementation (algorithms to optimization) - Thursday 9th July 2020

A one-day supplement to the Digital Signal Processing course that takes the theory and translates it into practice.
https://www.conted.ox.ac.uk/courses/digital-signal-processing-implementation-algorithms-to-optimisation
The course will include a mixed lecture and demonstration format and has been written to be independent of target processor architecture.
The course will show how to take common DSP algorithms and map them onto common processor architectures. It will also give a guide line for how to choose a DSP device, in particular how to choose and use the correct data word length for any application.

Attendee Feedback From Previous Courses :

It was informative, enjoyable and stimulating
Excellent content, very lively thanks to the 2 excellent presenters - Anonymous
A very good introduction to DSP theory
Excellent lecturers! Really useful information and very understandable
Great mix of theory and practice
The lecturers gave a detailed and excellent explanation of the fundamental topics of DSP with real world engineering practice.
This session closes the gap and clears up much confusion between classroom DSP theories and actual DSP implementation.
Very good session, with in-depth discussion on the math and background.


These courses will be held at the University of Oxford, UK

If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.

Evaluate The Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/