Skip to content
5 changes: 5 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
version: 2

build:
os: "ubuntu-22.04"
tools:
python: "3.12"

formats: all

python:
Expand Down
6 changes: 3 additions & 3 deletions activity-3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Activity 3: Actuation and feedback
Learning objectives
-------------------

Microcontroller do logic and mechanics, but you can't really get power out of them. In this activity, you will learn how to deliver power to a device attached to the microcontroller, and how to control this power to achieve a certain goal. This will transform the logical/mathematical capabilities of your micro-controller into actions that have effect on the real world.
Microcontrollers do logic and mechanics, but you can't really get power out of them. In this activity, you will learn how to deliver power to a device attached to the microcontroller, and how to control this power to achieve a certain goal. This will transform the logical/mathematical capabilities of your micro-controller into actions that have effect on the real world.
The activity relies on the skills that you have learned in the previous activities - you will use interrupts, read sensors, and maybe even solder again!


Expand All @@ -20,9 +20,9 @@ The aim is to implement a simple temperature controller.

Using a temperature sensor attached against one of the sides of a Peltier cell, your task is to keep constant the temperature it measures by transferring heat using the Peltier cell. The target temperature will be set in the code, and possibly changed by the user using the integrated button. The range of target temperatures should be close to ambient temperature (say within 5 degrees) to keep currents low enough.

If you plan primarily to cool down, it may be next to attach a heat sink on the hot side and the sensor on the other. If you plan to regulate temperatures larger than ambient temperature, do it the other way around. The heat sink helps dissipate the heat transferred on the side we do not wish to regulate, making it easier for the Peltier cell to do its job.
If you plan primarily to cool down, it may be useful to attach a heat sink on the hot side and the sensor on the other. If you plan to regulate temperatures larger than ambient temperature, do it the other way around. The heat sink helps dissipate the heat transferred on the side we do not wish to regulate, making it easier for the Peltier cell to do its job.

As an extra, you may want to consider ways to set the target temperature through the button.
As an extra, you may want to consider ways to change the target temperature through the button, or even a potentiometer if you have one.



Expand Down
3 changes: 1 addition & 2 deletions index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ University of Cambridge.

activity-1
activity-2
activity-3



Expand All @@ -32,7 +31,7 @@ These documents are licensed under a Creative Commons
Attribution-ShareAlike 4.0 International License. See
http://creativecommons.org/licenses/by-sa/4.0/ for the license.

Copyright 2017-2022 by A.J. Kabla, P.O. Kristensson, J. Durrell, F Forni.
Copyright 2017-2023 by A.J. Kabla, P.O. Kristensson, J. Durrell, F Forni.

Contact: ajk61@cam.ac.uk

Expand Down
2 changes: 1 addition & 1 deletion interrupts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ times when the button is pressed and its state fluctuates for a
little while.
To do this, we just need to force the program to wait a short time
after each call of the callback function.
This can be achieve by adding a wait function call in the callback function.
This can be achieved by adding a wait function call in the callback function.

Because it is not good practice to add a wait call in an interrupt (interrupt calls should execute fast),
the latest mbed compilers only allow us to use the `wait_us` function.
Expand Down
3 changes: 1 addition & 2 deletions introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ A few words about sponsors

This activity has been made possible by two sponsors.

- ARM and STMicroelectronics have donated the Nucleo microcontrollers, one
per undergraduate student. We are very grateful to them.
- ARM and STMicroelectronics have donated the Nucleo microcontrollers used in this lab. We are very grateful to them.

- The University of Cambridge provided financial support through a
Teaching And Learning Innovation Fund to run a number of student
Expand Down
11 changes: 4 additions & 7 deletions pointers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ We will use this later to tell the microcontroller what to do (i.e. what code to
For now, let's just look at a typical situation where this would be useful.
Imagine that you want to find the second derivative of a function :math:`f`.
To find a good numerical estimate, you can use the `central finite difference
<https://en.wikipedia.org/wiki/Finite_difference_coefficient>`_ relationship that you studied in first year:
<https://en.wikipedia.org/wiki/Finite_difference_coefficient>`_ relationship (that you may remember from your computing course):

.. math::

Expand Down Expand Up @@ -192,12 +192,9 @@ to output results, which is useful here to monitor what happens.
Note that we need to specify fully in the declaration of second_derivative the types of the input and output of the function we will pass: ``float (*f)(float)``. This makes sure the compiler also knows how to interact with the function, i.e. how to package its input, and how to interpret its output.

This example may look confusing if you are reading attentively enough.
<<<<<<< HEAD
Why didn't we pass the address of the function, using ``second_derivative(&f_1, 1)``?
Why didn't we call the function f using ``(*f)(x)`` in the second_derivative function?
=======
Since second_derivative takes a pointer to a function as parameter, why didn't we pass the address of the function, using second_derivative(&f_1, 1)? Why didn't we call the function f using (\*f)(x) in the second_derivative function?
>>>>>>> master

Since ``second_derivative`` takes a pointer to a function as parameter, why didn't we pass the address of the function, using ``second_derivative(&f_1, 1)``? Why didn't we call the function f using ``(\*f)(x)`` in the second_derivative function?


The reason is that a function name is already treated by the compiler as a pointer to the function code, to make the program more readable.
There is some flexibility in the syntax though, and you could also have used the following syntax for the calculation of the second derivative:
Expand Down
7 changes: 6 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
docutils<0.18
sphinx==6.2.1
sphinx-rtd-theme==1.2.2
mock==1.0.1
commonmark==0.9.1
recommonmark==0.5.0
docutils>=0.18

2 changes: 1 addition & 1 deletion serial-communication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The code below shows how to capture information from the user through the Serial

.. code-block:: c

include "mbed.h"
#include "mbed.h"

Serial pc(SERIAL_TX, SERIAL_RX);

Expand Down