From: Pavel Pisa
+The goal was to prove that working control can be achieved with +Embedded Realtime Linux Target for Simulink +(ert_linux) on this low cost hardware which provides option for broader +community to play with this control task taught during the +real-time operating +systems programming course at our university. The final task +assignment +targets industrial like PowerPC MPC5200-based board running VxWorks system. +But Raspberry Pi (RPi) is much cheaper and common in broad community. +The initial idea has been implemented in a frame of Radek MeÄiar's +bachelor thesis with controller and monitor web server implemented +directly in C-language. The experiment has been improved and combined +with ert_linux project to allow teach controller design with Simulink. +
+ [[!img rpi-mc-wwrap-schema.png size="300x" align=right alt="Diagram of Interconnection of RPi and DC Motor"]] -The DC motor is connected to RPi GPIO pins. -The diagram of wire-wrapped interconnection is available in -PDF and ++Since the RPi (and its BCM2835 SoC) is not intended for motion control applications, +there is no hardware support for incremental encoder inputs (IRC) +and the RPi connector has only one pulse width modulation (PWM) output. +That is why most of signal and control processing is done in software +with minimal HW support. In order to be able to rotate the motor in both +directions, the only available PWM signal is demultiplex to two +sides of power H-bridge by using four NOR gates (SN74HCT02) +where direction is controlled by an additional GPIO output (DIR). +The incremental encoder signals are connected directly to the RPi and +processed only in software. The diagram of wire-wrapped interconnection +is available in PDF and SVG formats as well.
++The IRC signal processing is the most demanding part of our solution +since the frequency of the IRC signal can go up to 21 kHz, +when maximal voltage is applied to the motor. To achieve reasonable +performance, a kernel driver has been implemented for this purpose. +It uses four GPIO pins — two for each IRC channel. +One of these two pins is configured to generate interrupts for +rising edges and the other for falling edges. Motor position is +derived from the order of interrupts and applications can read it via +/dev/irc0. +
++This solution has an interesting property that it works even when the +processing of one (or few more) interrupt(s) is delayed due to other +activities in the system. In preempt_rt, the interrupt handlers run +in dedicated threads, which can be preempted by threads with higher +priority. Thanks to the fact that the scheduler run queue is a FIFO +queue, the IRQ threads are activated in the same order as the original +interrupts and our position calculation works even in the case of +a delay. The alternative approach, where the position is calculated from +the actual IRC signal levels read in the interrupt handler would fail, +because the level read in a delayed handler might be different from +the level at the time when the corresponding IRQ was generated. +
++Even better performance could be probably achieved by processing the +IRC signals in ARM's fast interrupt requests (FIQ), but this solutions +would not be portable to other architectures. Other option is to +design more sophisticated hardware but minimal HW solution is +excellent for teaching. +
+ ++Simulink model of the motor controller is depicted in Figure. +The +IRC0 +and +PWMwDir +blocks are so called C MEX S-functions. The former reads the motor position +from /dev/irc0, the latter controls the PWM and DIR signals +by directly accessing the GPIO registers via mmap()ed /dev/mem. +The actual motor control is performed by a proportional-sum-derivative (PSD) +controller enhanced with an anti-windup technique. Setpoint w +is generated either manually or by a simple trajectory generator. +Sampling period of the whole model was set to 1 ms. The source code +of the S-functions as well as the model are available from +Github repository. +
++The ert_linux target was configured to use an ARM C cross-compiler. +The generated binary was copied to the target RPi board by the +scp command and ran there. Simulink external mode was +used to tune certain model parameters on-line as well as to see the +actual signal values in the scope windows. +
+ ++The Linux kernel used for our experiments was the official +Raspberry Pi rpi-3.12.y Linux kernel version 3.12.28 patched with Steven +Rostedt's stable preempt_rt patch (patch-3.12.26-rt40) and with Junjiro R. +Okajima's aufs3.12.x 20140512. The latencies measured by the cyclictest +tool when the system was loaded by TCP communication and SD card accesses are as +follows. The maximal latency was 170 μs, average about 40 μs. When +graphical desktop was run the maximal latencies increased to 280 μs +(probably caused by contention on the system bus generated by the +VideoCore GPU). This observation is in same range as +more serious examination and long term performance monitoring +on better tuned RT-kernel kernel executed by +Open Source Automation Development Lab +and documented in their +Quality assurance Farm. +
++System load caused by running an unoptimized (soft-float only) model +was about 2%. The USB connected Ethernet controller (a part of RPi) generated +load of about 10%. The highest load was generated by the software IRC +signal processing — up to 95%, i.e. the limit for RT tasks. This +happened during fast motor rotation (e.g. when maximal input voltage +was applied) and the interrupt frequency was 8 kHz per each channel +(32 kHz in total). As can be seen, processing of the IRC signal at +full speed (21 kHz) is above capabilities of the Linux kernel on this +hardware. As mentioned above, the use of FIQ (or raw interrupts) could +help here. For lower speeds, our simple solution works flawlessly and +can be used as a great tool for control education and experiments. +
+ +