<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>BPRJ Product Development on BPRJ Product Development Limited</title><link>https://www.bprj.co.uk/</link><description>Recent content in BPRJ Product Development on BPRJ Product Development Limited</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><lastBuildDate>Sun, 17 Jun 2018 16:05:21 +0100</lastBuildDate><atom:link href="https://www.bprj.co.uk/index.xml" rel="self" type="application/rss+xml"/><item><title>Nuisance Call and Spam</title><link>https://www.bprj.co.uk/news/2018-06-17-nuisance-call-and-spam/</link><pubDate>Sun, 17 Jun 2018 19:57:16 +0000</pubDate><guid>https://www.bprj.co.uk/news/2018-06-17-nuisance-call-and-spam/</guid><description>The following is a link to a white paper discussing the problem of spam, nuisance/fake calls and identity theft and the technology that can be used to solve that problem: White paper – C21 comms</description></item><item><title>Application-provided routines</title><link>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/application-provided-routines/</link><pubDate>Sun, 17 Jun 2018 18:03:03 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/application-provided-routines/</guid><description>execAppCurrentTick() Function prototype:
word execAppCurrentTick(void); Parameters: None
Returns: the current value of the main timer (the current timer tick).
This function is not part of the executive but is user-supplied and called by the executive when a timer is being activated.
This function should query the hardware or other timer/counting mechanism used to implement the timer system.
execAppFinish() Function prototype:
void execAppFinish(void); Parameters: None
Returns: Nothing
This function is not part of the executive but is user-supplied and called only when running under Windows when the executive shuts down.</description></item><item><title>Asynchronous communications protocol functions</title><link>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/asynchronous-communications-protocol-functions/</link><pubDate>Sun, 17 Jun 2018 18:03:03 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/asynchronous-communications-protocol-functions/</guid><description>Important Points The protocol is designed for use on multi-drop master-slave arrangements such as RS485. The protocol supports a master and up to 254 slave nodes (although RS485 physically supports only up to 32 nodes on a given link). The protocol also supports broadcast, which is implemented by transmitting on a node number of 255. The protocol can also be used with a point-to-point arrangement such as RS232.
The protocol uses a half-duplex poll-response system, where the master polls one node at a time, and that node responds before the master polls that node again or moves onto another one.</description></item><item><title>Data queue functions</title><link>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/data-queue-functions/</link><pubDate>Sun, 17 Jun 2018 18:03:03 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/data-queue-functions/</guid><description>execDataQueueOk() Function prototype:
boolean execDataQueueOk (byte *Queue, word or byte QueueSize); Parameters: Queue the queue to get the data from
QueueSize the size of the queue in bytes
Returns: true if the queue is not corrupted. It will return false if the queue’s internal data structures (pointers, etc.) imply that queue entries exist outside the memory extent of the queue or overlap one another.
The QueueSize is the size of the Queue array in bytes, which is best obtained using the sizeof() operator.</description></item><item><title>Event processing functions</title><link>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/event-processing-functions/</link><pubDate>Sun, 17 Jun 2018 18:03:03 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/event-processing-functions/</guid><description>execDeleteEvent() Function prototype:
boolean execDeleteEvent(word or byte Event); Parameters: Event posted event to be cancelled
Returns: true if an event of that number was found and cancelled or false if not.
This function searches all the queues from the highest priority (event at the front of the queue) to the lowest and substitutes an event number of zero in every occurrence it finds.
It is recommended only to use this function if no other means of achieving this result can be done (i.</description></item><item><title>Running under Microsoft Windows</title><link>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/running-under-microsoft-windows/</link><pubDate>Sun, 17 Jun 2018 18:03:03 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/running-under-microsoft-windows/</guid><description>Important Points The entire executive will compile and run under Windows without modification, and additionally requires the module ‘ExecWin.c’ which defines Windows-specific functionality.
The Windows-specific file has been designed for compilation under Microsoft Visual C/C++, although it may work with other Windows C compilers.
The executive and application must be compiled and linked using the multithreaded C libraries (a non-default option in Microsoft C/C++).
The execAppIdle() function must call the execSafeCpuIdle() function, because shutdown of the executive is performed from this function (and it also allows the proper yielding of execution in the Windows pre-emptive multitasking environment).</description></item><item><title>State machine functions</title><link>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/state-machine-functions/</link><pubDate>Sun, 17 Jun 2018 18:03:03 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/state-machine-functions/</guid><description>execCancelStateTransition() Function prototype:
void execCancelStateTransition(void); Parameters: none
Returns: nothing
For the currently executing state machine, the current state number is copied to the next state number.
This function should not be called from an interrupt routine as it will cause unpredictable results.
execDisableStateMachine() Function prototype:
boolean execDisableStateMachine(word or byte Machine); Parameters: Machine state machine to be disabled
Returns: true if it succeeded or false if it failed. It will fail if the parameter passed is invalid.</description></item><item><title>System and other functions</title><link>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/system-and-other-functions/</link><pubDate>Sun, 17 Jun 2018 18:03:03 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/system-and-other-functions/</guid><description>execCheckIntegrity() Function prototype:
byte execCheckIntegrity(byte WhatToCheck); Parameters: WhatToCheck checks as defined below
Returns: sum of failed checks as below (0 = passed).
The following checks can be performed:
Do all the (global) events belong to a valid state machine? (1) Do all the (global) events correspond to a valid local event within its state machine? (2) Do all the events have valid default priorities? (4) Do all the state transitions in the state machines call up valid states for that state machine (0 is invalid)?</description></item><item><title>Timer functions</title><link>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/timer-functions/</link><pubDate>Sun, 17 Jun 2018 18:03:03 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-program-interface/timer-functions/</guid><description>execKillTimer() Function prototype:
boolean execKillTimer(word or byte Timer); Parameters: Timer the number of the timer to disable (kill)
Returns: true if it succeeded or false if it failed. It will fail if an invalid timer number is passed (but not if the timer has already been killed).
This disables the timer, but does not remove any pending events posted by that timer. Use execPurgeTimer if this is required.
execProcessTimeouts() Function prototype:</description></item><item><title>Application example</title><link>https://www.bprj.co.uk/the-state-event-executive/application-example/</link><pubDate>Sun, 17 Jun 2018 14:29:04 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-example/</guid><description>Script for Generating Source Code Tables The following Python script, Widget.py, will generate the declarations and tables for the example in the rest of this section, but the code examples that follow have not been generated using this facility.
import sys sys.path.append(&amp;#34;..\\exec&amp;#34;) # for ExecStuff, assuming exec is in this directory from ExecStuff import * ############# Complete set of definitions for exec, etc. ###################### Definition = { &amp;#39;Event Queues&amp;#39; : ((&amp;#39;BACKGND_QUEUE&amp;#39;, 128), (&amp;#39;LOW_QUEUE&amp;#39;, 32), (&amp;#39;INTERMED_QUEUE&amp;#39;, 32), (&amp;#39;TOP_QUEUE&amp;#39;, 8) ), &amp;#39;State Tables&amp;#39; : ( ( &amp;#39;smSingleTransition&amp;#39;, (&amp;#39;SM_SINGLE_STATE&amp;#39;, &amp;#39;STATE1&amp;#39;), # ======================================================================== ((&amp;#39;EV_STATUS_REQUEST&amp;#39;, &amp;#39;BACKGND_QUEUE&amp;#39;), (&amp;#39;STATE1&amp;#39;, 0, &amp;#39;HandleStatusRequest&amp;#39;)), ((&amp;#39;EV_SCAN_TRIGGER&amp;#39;, &amp;#39;TOP_QUEUE&amp;#39;), (&amp;#39;STATE1&amp;#39;, 0, &amp;#39;ScanInputs&amp;#39;)) ), ( &amp;#39;smWidgetTransition&amp;#39;, (&amp;#39;SM_WIDGET_SEQUENCER&amp;#39;, &amp;#39;WIDGET_IDLE&amp;#39;, &amp;#39;ENTERING_SLOT&amp;#39;, &amp;#39;LEAVING_SLOT&amp;#39;, &amp;#39;ENTERING_TRAY&amp;#39;, &amp;#39;AWAITING_REMOVAL&amp;#39;, &amp;#39;FAULTY&amp;#39;), # ===================================================================== ((&amp;#39;EV_DOOR_READY&amp;#39;, &amp;#39;INTERMED_QUEUE&amp;#39;), (&amp;#39;ENTERING_SLOT&amp;#39;, 0, &amp;#39;DispenseWidget&amp;#39;), # WIDGET_IDLE (&amp;#39;ENTERING_SLOT&amp;#39;, 0, None), # ENTERING_SLOT (&amp;#39;LEAVING_SLOT&amp;#39;, 0, None), # LEAVING_SLOT (&amp;#39;ENTERING_TRAY&amp;#39;, 0, None), # ENTERING_TRAY (&amp;#39;ENTERING_SLOT&amp;#39;, 0, &amp;#39;DispenseWidget&amp;#39;), # AWAITING_REMOVAL (&amp;#39;FAULTY&amp;#39;, 0, None)), # FAULTY ((&amp;#39;EV_WIDGET_IN_SLOT&amp;#39;, &amp;#39;INTERMED_QUEUE&amp;#39;), (&amp;#39;FAULTY&amp;#39;, 1, &amp;#39;LogWidgetFault&amp;#39;), # WIDGET_IDLE (&amp;#39;LEAVING_SLOT&amp;#39;, 0, None), # ENTERING_SLOT (&amp;#39;LEAVING_SLOT&amp;#39;, 0, None), # LEAVING_SLOT (&amp;#39;FAULTY&amp;#39;, 3, &amp;#39;LogWidgetFault&amp;#39;), # ENTERING_TRAY (&amp;#39;FAULTY&amp;#39;, 3, &amp;#39;LogWidgetFault&amp;#39;), # AWAITING_REMOVAL (&amp;#39;FAULTY&amp;#39;, 0, None)), # FAULTY ((&amp;#39;EV_SLOT_CLEAR&amp;#39;, &amp;#39;INTERMED_QUEUE&amp;#39;), (&amp;#39;WIDGET_IDLE&amp;#39;, 0, None), # WIDGET_IDLE (&amp;#39;ENTERING_SLOT&amp;#39;, 0, None), # ENTERING_SLOT (&amp;#39;ENTERING_TRAY&amp;#39;, 0, &amp;#39;HandleWidget&amp;#39;), # LEAVING_SLOT (&amp;#39;ENTERING_TRAY&amp;#39;, 0, None), # ENTERING_TRAY (&amp;#39;AWAITING_REMOVAL&amp;#39;,0,None), # AWAITING_REMOVAL (&amp;#39;FAULTY&amp;#39;, 0, None)), # FAULTY ((&amp;#39;EV_WIDGET_IN_TRAY&amp;#39;, &amp;#39;INTERMED_QUEUE&amp;#39;), (&amp;#39;FAULTY&amp;#39;, 2, &amp;#39;LogWidgetFault&amp;#39;), # WIDGET_IDLE (&amp;#39;FAULTY&amp;#39;, 2, &amp;#39;LogWidgetFault&amp;#39;), # ENTERING_SLOT (&amp;#39;AWAITING_REMOVAL&amp;#39;,0,&amp;#39;StopWidget&amp;#39;), # LEAVING_SLOT (&amp;#39;AWAITING_REMOVAL&amp;#39;,0,&amp;#39;StopWidget&amp;#39;), # ENTERING_TRAY (&amp;#39;AWAITING_REMOVAL&amp;#39;,0,None), # AWAITING_REMOVAL (&amp;#39;FAULTY&amp;#39;, 0, None)), # FAULTY ((&amp;#39;EV_TRAY_CLEAR&amp;#39;, &amp;#39;INTERMED_QUEUE&amp;#39;), (&amp;#39;WIDGET_IDLE&amp;#39;, 0, None), # WIDGET_IDLE (&amp;#39;ENTERING_SLOT&amp;#39;, 0, None), # ENTERING_SLOT (&amp;#39;LEAVING_SLOT&amp;#39;, 0, None), # LEAVING_SLOT (&amp;#39;WIDGET_IDLE&amp;#39;, 0, &amp;#39;RecordWidget&amp;#39;), # ENTERING_TRAY (&amp;#39;WIDGET_IDLE&amp;#39;, 0, &amp;#39;RecordWidget&amp;#39; ), # AWAITING_REMOVAL (&amp;#39;FAULTY&amp;#39;, 0, None)), # FAULTY ((&amp;#39;EV_WIDGET_TIMEOUT&amp;#39;, &amp;#39;INTERMED_QUEUE&amp;#39;), (&amp;#39;WIDGET_IDLE&amp;#39;, 0, None), # WIDGET_IDLE (&amp;#39;FAULTY&amp;#39;, 10, &amp;#39;LogWidgetFault&amp;#39;), # ENTERING_SLOT (&amp;#39;FAULTY&amp;#39;, 10, &amp;#39;LogWidgetFault&amp;#39;), # LEAVING_SLOT (&amp;#39;FAULTY&amp;#39;, 10, &amp;#39;LogWidgetFault&amp;#39;), # ENTERING_TRAY (&amp;#39;WIDGET_IDLE&amp;#39;, 0, &amp;#39;RecordWidget&amp;#39;), # AWAITING_REMOVAL (&amp;#39;WIDGET_IDLE&amp;#39;, 0, None)) # FAULTY ), ( &amp;#39;smDoorTransition&amp;#39;, (&amp;#39;SM_DOOR_CONTROL&amp;#39;, &amp;#39;DOOR_CLOSED&amp;#39;, &amp;#39;DOOR_OPENING&amp;#39;, &amp;#39;DOOR_OPEN&amp;#39;, &amp;#39;DOOR_CLOSING&amp;#39;), # =================================================================== ((&amp;#39;EV_BUTTON_PUSHED&amp;#39;, &amp;#39;LOW_QUEUE&amp;#39;), (&amp;#39;DOOR_OPENING&amp;#39;, 0, &amp;#39;OpenDoor&amp;#39;), # DOOR_CLOSED (&amp;#39;DOOR_OPENING&amp;#39;, 0, None), # DOOR_OPENING (&amp;#39;DOOR_OPEN&amp;#39;, 0, None), # DOOR_OPEN (&amp;#39;DOOR_OPENING&amp;#39;, 0, &amp;#39;OpenDoor&amp;#39;)), # FAULTY ((&amp;#39;EV_DOOR_OPEN&amp;#39;, &amp;#39;LOW_QUEUE&amp;#39;), (&amp;#39;DOOR_CLOSED&amp;#39;, 0, None), # DOOR_CLOSED (&amp;#39;DOOR_OPEN&amp;#39;, 0, &amp;#39;TriggerWidget&amp;#39;), # DOOR_OPENING (&amp;#39;DOOR_OPEN&amp;#39;, 0, None), # DOOR_OPEN (&amp;#39;DOOR_CLOSING&amp;#39;, 0, None)), # FAULTY ((&amp;#39;EV_DOOR_CLOSED&amp;#39;, &amp;#39;LOW_QUEUE&amp;#39;), (&amp;#39;DOOR_CLOSED&amp;#39;, 0, None), # DOOR_CLOSED (&amp;#39;DOOR_OPENING&amp;#39;, 0, None), # DOOR_OPENING (&amp;#39;DOOR_OPEN&amp;#39;, 0, None), # DOOR_OPEN (&amp;#39;DOOR_CLOSING&amp;#39;, 0, None)), # FAULTY ((&amp;#39;EV_DOOR_TIMEOUT&amp;#39;, &amp;#39;LOW_QUEUE&amp;#39;), (&amp;#39;DOOR_CLOSED&amp;#39;, 0, None), # DOOR_CLOSED (&amp;#39;DOOR_CLOSING&amp;#39;, 0, &amp;#39;CloseDoor&amp;#39;), # DOOR_OPENING (&amp;#39;DOOR_CLOSING&amp;#39;, 0, &amp;#39;CloseDoor&amp;#39;), # DOOR_OPEN (&amp;#39;DOOR_CLOSING&amp;#39;, 0, None)) # FAULTY ), ), &amp;#39;Timers&amp;#39; : (&amp;#39;WIDGET_TIMER&amp;#39;, &amp;#39;DOOR_TIMER&amp;#39;), &amp;#39;Comms&amp;#39; : ((&amp;#39;boolean&amp;#39;, &amp;#39;byte&amp;#39;, &amp;#39;sbyte&amp;#39;, &amp;#39;word&amp;#39;, &amp;#39;sword&amp;#39;, &amp;#39;lword&amp;#39;, &amp;#39;slword&amp;#39;), ((&amp;#39;StatusDef&amp;#39;, &amp;#39;StatusDefDescriptor&amp;#39;, 1), (&amp;#39;byte&amp;#39;, &amp;#39;ID&amp;#39;, 1), (&amp;#39;lword&amp;#39;, &amp;#39;Flags&amp;#39;, 2), (&amp;#39;DateTimeDef&amp;#39;, &amp;#39;Timestamp&amp;#39;, 1)), ((&amp;#39;DateTimeDef&amp;#39;, None, 0), (&amp;#39;byte&amp;#39;, &amp;#39;Hour&amp;#39;, 1), (&amp;#39;byte&amp;#39;, &amp;#39;Minute&amp;#39;, 1), (&amp;#39;byte&amp;#39;, &amp;#39;Second&amp;#39;, 1), (&amp;#39;byte&amp;#39;, &amp;#39;Day&amp;#39;, 1), (&amp;#39;byte&amp;#39;, &amp;#39;Month&amp;#39;, 1), (&amp;#39;word&amp;#39;, &amp;#39;Year&amp;#39;, 1)) ), &amp;#39;Source Files&amp;#39; : (&amp;#39;Widget.</description></item><item><title>Application-provided data structures</title><link>https://www.bprj.co.uk/the-state-event-executive/application-provided-data-structures/</link><pubDate>Sun, 17 Jun 2018 14:29:04 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/application-provided-data-structures/</guid><description>Event Definition Table This is defined as follows:
struct execEventDef { byte DefaultPriority; byte LocalEventNumber; word or byte StateMachineNumber; }; struct execEventDef execEvent[TOTAL_EVENTS]; Each event is given a unique number in the system which is either a byte or a word, depending on the number of events in the system (the event queues can be defined to be bytes or words, depending on build options). This number is an index into this table.</description></item><item><title>Design and implementation details of the executive</title><link>https://www.bprj.co.uk/the-state-event-executive/design-and-implementation-details-of-the-executive/</link><pubDate>Sun, 17 Jun 2018 14:29:04 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/design-and-implementation-details-of-the-executive/</guid><description>Posting Events Posting events is done by the function execPostPriorityEvent (execPostEvent is a macro which calls execPostPriorityEvent with the default priority for the event).
This must work whether it is called from a state transition function or an interrupt, including interrupts of higher priority that have interrupted other interrupt routines. The posting function therefore has to lock out access to the event queue (by suspending interrupts) during the critical parts of this operation.</description></item><item><title>Development to date</title><link>https://www.bprj.co.uk/the-barnabas-motion-system/development-to-date/</link><pubDate>Sun, 17 Jun 2018 14:29:04 +0100</pubDate><guid>https://www.bprj.co.uk/the-barnabas-motion-system/development-to-date/</guid><description>A design-proving prototype has been constructed and tested. This consists of a single-rotor ride-on vehicle, driven from a small DC motor and batteries. A flywheel is used on the motor, and the steering and speed controls are entirely mechanical. Trailing wheels are used to prevent undesired rotation of the entire vehicle.
Very rapid acceleration and deceleration was demonstrated as predicted. The controls were light and easy to use.
Regeneration on slow-down was also demonstrated.</description></item><item><title>How does it work?</title><link>https://www.bprj.co.uk/the-barnabas-motion-system/how-does-it-work/</link><pubDate>Sun, 17 Jun 2018 14:29:04 +0100</pubDate><guid>https://www.bprj.co.uk/the-barnabas-motion-system/how-does-it-work/</guid><description>The adjacent diagram is a plan view (view from above) of 5 wheels, shown in blue, driven together in the direction of the grey arrow, steered by axles which are red. All 5 wheels are attached to a single rotor which rotates about an axis normal to the plane on which the wheels run, and this axis is represented by the centre of the green cross. Each wheel is individually steered about its own vertical axis (normal to the plane), and this axis passes through the centre of the contact area of the wheel and the surface below (similar to a castor, except that there is no offset distance of the vertical steering axis).</description></item><item><title>How to use it and how it works</title><link>https://www.bprj.co.uk/the-state-event-executive/how-to-use-it-and-how-it-works/</link><pubDate>Sun, 17 Jun 2018 14:29:04 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/how-to-use-it-and-how-it-works/</guid><description>The first and most important feature that must be appreciated is that applications written using the executive do not have a start and thread of execution in the conventional sense. There is no ‘main’ function (although this actually exists as part of the executive itself). Every item of processing that is performing is done in response to an event, with the exception of initialisation which is performed in an application-provided routine, called by the executive on start-up.</description></item><item><title>Test harness facilities</title><link>https://www.bprj.co.uk/the-state-event-executive/test-harness-facilities/</link><pubDate>Sun, 17 Jun 2018 14:29:04 +0100</pubDate><guid>https://www.bprj.co.uk/the-state-event-executive/test-harness-facilities/</guid><description>Introduction Applications written using the State-Event Executive can be tested in a scripting or other controlled test environment with the aid of the facilities described in this section.
A special version of various application-defined facilities is used to enable this, as defined in ExecTest.c and TestDep.h. This allows timers and events to be progressed under full control test facility itself, so that testing is not subject to the passage of real time, and so that the state of a system’s internal data can be verified at any point in its sequence of events.</description></item><item><title>What is it useful for?</title><link>https://www.bprj.co.uk/the-barnabas-motion-system/what-is-it-useful-for/</link><pubDate>Sun, 17 Jun 2018 14:29:04 +0100</pubDate><guid>https://www.bprj.co.uk/the-barnabas-motion-system/what-is-it-useful-for/</guid><description>Its key feature is the ability to rapidly accelerate and decelerate in an energy efficient way and for low purchase and running costs. These advantages are significant when compared with the use of hydraulics to perform similar tasks.
The following is a list of some of the possible applications:
Motion in small training simulators (e.g. driver training) and arcade games. Motion in larger non-interactive entertainment simulators. This system has the advantage of being able to have a large X-Y movement capability, giving a greater sensation of forward acceleration, etc.</description></item><item><title>Products</title><link>https://www.bprj.co.uk/products/</link><pubDate>Sun, 17 Jun 2018 14:21:02 +0100</pubDate><guid>https://www.bprj.co.uk/products/</guid><description>We have 2 products available that we have developed:
The Barnabas Motion System This is a patented and simple low-cost means of converting largely unregulated rotary motion into precisely controlled, and highly dynamic motion in two linear dimensions.
The State-Event Executive This is a special kind of real-time operating system for small (highly memory-constrained) microcontrollers. It uses finite state machines driven by events to provide a fast and highly portable, non-pre-emptive, multi-tasking programming environment.</description></item><item><title>Contact Us</title><link>https://www.bprj.co.uk/correspond/</link><pubDate>Sun, 17 Jun 2018 13:50:48 +0100</pubDate><guid>https://www.bprj.co.uk/correspond/</guid><description>Nigel Hathaway Consultant
40 Uplands Road
Saltford
Bristol BS31 3JJ
UK
Tel +44 870 490 9688
Fax +44 845 868 4382
Linked In
Alternatively, you may contact us using the form below:
Your message has been sent. You should get a reply in due course.
Unfortunately it has not been possible to send your message:
.
Name
First and last names
E-mail address
I will get back to you at this address
Message
Please, no links or other advertising.</description></item><item><title>Legal Information</title><link>https://www.bprj.co.uk/legal-info/</link><pubDate>Sun, 17 Jun 2018 13:50:47 +0100</pubDate><guid>https://www.bprj.co.uk/legal-info/</guid><description>BPRJ Product Development Limited is registered in England No. 7778141.
Registered office: 40 Uplands Road, Saltford, Bristol BS31 3JJ. UK.</description></item><item><title>Nigel Hathaway</title><link>https://www.bprj.co.uk/services/nigel-hathaway/</link><pubDate>Sun, 17 Jun 2018 13:46:25 +0100</pubDate><guid>https://www.bprj.co.uk/services/nigel-hathaway/</guid><description>Nigel was the original founder of the company back in 1989. Although originally an electronic design engineer, he has recently focused on systems and software designs. His principal experience is in the realm of embedded systems, small and large, although he also has significant experience in the area of data processing systems and IT, particularly where those systems integrate with embedded products. His wide-ranging experience in different technologies, and product design starting with a clean sheet, make him ideally suited for working with product start-ups, where early design decisions have a profound effect on the final performance of the product and its development cost.</description></item></channel></rss>