Don’t trust the internet (and how to add an Inductive Proximity Sensor to your 3D printer the proper and easiest way)

Every now and then I still fall for it. Whenever I’m trying to accomplish something I’ve never done before, I start a Google search to find some nice video’s or blog posts that explain how I can accomplish this specific kind of task. That in itself is perfectly fine, however… one should not stop using its own brain!

This week I wanted to add an Inductive Proximity Sensor (LJ12A3-4-Z/BX) to my 3D printer as touching the printer bed while measuring the distance towards the printer bed has an actual effect on the measurement.. duh. Especially when you have a round aluminium printer bed that has supports at three “corners” only.

Side note (1): The main reason I own a 3D printer is that I’m into electronics  – I like to built and program my own IoT hardware – and wanted to be able to print my own custom cases.

So let me refer you to some contents on the internet that explain how to install this proximity sensor:

They all tell you to work with a voltage divider as these sensors are powered by 6V to 36V, which means that their signal wire can be at that level to. Most 3D printer control boards however are Atmega based, which have max input of 5.5V. My MKS Base V1.5 printer board, is indeed based on an Atmega 2560 and suffers that same limitation.

This all seemed very legit, so without thinking, I started to built a voltage divider, following their samples. I started out by combining 6.8kΩ and 4.7kΩ as this does stay within the standard range of “pull-up” values which is between 4.7kΩ and 10kΩ.

Standard voltage divider
Voltage divider v1

Tested my voltage divider with a 9 volts battery, and it all worked out fine. So let’s tear down my printer and add the proximity sensor. Installed the sensor together with the divider and… nothing! I then tested the voltage divider in combination with the sensor (don’t ask me why I didn’t test it with the sensor the first time) and noticed that the output, which should be around 5V, was around 2.5V only. OK, that might be an indication that the supplied current is not enough to maintain the “high” voltage when we are “pissing” away 2.5 mA towards Gnd. That is a bit weird as 2.5 mA is not that much, but let’s give it a try by using some higher value  resistors. I don’t have the 15kΩ and 10kΩ mentioned in the video at hand so let’s take a 68kΩ and 47kΩ!

Voltage divider with very high resistance
Voltage divider with very high resistance

I was amazed as well, but indeed, this seemed to be the solution as the measured voltage now was 4.5V. Still to far off in my opinion, but it is high enough to pass as a logic high so let’s continue. Connect the sensor, configure the printer firmware and see what’s happening! Ehmm… nothing. Even though the sensor’s LED lights up when I approach it with something metal, the printer software still says NO.

Let’s take the digital multi meter at hand again and see what’s going on. We first measure the sensing pin on the printer board. I’m pretty sure I disabled the pull-up in the firmware so we should measure either a floating pin, or something close to GND.

Side note (2): In electronics we do not like floating pins. We either pull them softly, but fully, up towards Vdd or down to GND.

But wait! It reads a high 5V! That’s not good. Verified my firmware and the pull-up is indeed disabled, so did they add some hardware pull-ups?

Please tell me they didn’t. Because if they did add a standard hardware pull-up between 4.7kΩ and 10kΩ , I will indeed never be able to pull it down to LOW through the 68kΩ resistor in my voltage divider. OK, getting a bit tired of it but, never give up and search for the schematics on the printer board then.

You can find some sort of design of the board on GitHub, but that is not detailed enough. Luckily I found someone with the same issue that I had and he had a solution! Hurrah, all I needed to do was to remove some resisters from the printer board and then it will all work. So I prepared my soldering iron to attack my printer board and then……

NOOOOOH, of course not. It was just then when I finally decided to use my own brains. I should be able to solve this myself! Serious? I almost got medieval on the ass of my printer board with a soldering iron.

So let’s use our brain and look at the schematics of these type of sensors.

Sensor_ wiring_NPN_PNP
Sensor wiring NPN PNP

The sensor type I’ve got is NPN NO which means that you measure the BLACK line and:

  • when it is not sensing anything inductive nearby, it should be open and thus floating
  • when it is sensing anything inductive nearby, it will be connected to GND

Hmmm… floating. Remember when I said we don’t like floating pins in electronics? We would like to have either all or nothing. So in this case, the following will most probably be true:

  • when it is not sensing anything inductive nearby, it will be pulled up to Vdd
  • when it is sensing anything inductive nearby, it will be connected to GND

So let’s draw a logical design on how an NPN transistor with a pull-up would look like.

Logical NPN with pull-up
Logical NPN with pull-up

We should be able to measure that with a digital multi meter. Just measure the resistance between BLACK and BROWN. I did and guess what? I indeed measured an almost perfect standard pull-up value of 10kΩ.

But wait a second… that’s why our voltage divider gave such weird values! What we thought was this:

Standard voltage divider
Voltage divider v1

Actually was this:

Actual voltage divider
Actual voltage divider

And that’s why it all didn’t work. Once we started to create a voltage divider with insane values it started to work as the 10kΩ did not have that high of an impact any more.

We can now also answer the question of how we actually should connect our NPN sensor to our printer board. We do need a voltage divider, but one of the resistor values is already given. We can use the following formula to calculate the required value of the second resistor R2:

Voltage divider formula
Voltage divider formula

Or navigate to http://www.raltron.com/cust/tools/voltage_divider.asp if we are lazy.

The output should be 7142.86Ω.

To be on the safe side we pick a standard value which is less so we end up with 6.8kΩ. Our final solution just looks like this:

Final solution
Final solution

Indeed, all we need to do is add a single 6.8kΩ resistor between BLACK and BLUE and all should work fine.

Once the single resistor was added, I verified all voltages with my digital multi meter and it all worked perfectly fine.

Don’t forget that you do need to change your firmware because we still need to invert our end stop. It is HIGH when not triggered and LOW when triggered.

const bool Z_MIN_ENDSTOP_INVERTING = true;

So after all I got it working in the easiest, cheapest and most logical way one can, simply by using my own brain.

The moral of this story is to never stop thinking yourself and to not blindly trust all stories on the internet. Use your brains!

That being said! Don’t just do as this posts says! First you have to verify which type of sensor you’ve got. If you have a NPN type of sensor, you should be able to measure the 10kΩ pull-up resistor between BROWN and BLACK. If you have a PNP type of sensor, you will most probably(I don’t own one) be able to measure the 10kΩ pull-down resistor between the BLACK and BLUE. In case you’ve got a PNP type of sensor, the very first voltage divider should indeed be used.

Standard voltage divider
Voltage divider v1

One thing is sure. IF you do connect your sensor to 12V (which you should as that is within the specs!) you should not go without any voltage regulation, even though many people suggest you should. It doesn’t matter which type of sensor, you should not connect them as is to your signal wire if the sensor is connected to 12V.

***UPDATE***

Boris had a perfect comment on using a diode instead. And, believe it or not but, using a 1N4148 diode was my first solution. So I did test using a diode and that also works perfectly fine, simply because the direction in which the 12V current would like to flow when the sensor is open will be blocked by the diode. The internal (or hardware) pull-up still pulls the Atmega’s sensor pin to HIGH however.

Current flow when the sensor is open
Current flow when the sensor is open

But as soon as the sensor is closed, the diode would allow the 5V current to flow in the opposite direction towards ground, which pulls the Atmega’s sensor pin to LOW.

Current flow when the sensor is closed.
Current flow when the sensor is closed.

So both the proper voltage divider and a diode can do the job. Which one you prefer… well, the diode might actually be safer to use (they often call it a protection diode with a reason ;-)) if installed correctly, but it also depends on what you have at hand and even what you prefer I guess. The reason I preferred to explain the voltage divider in the first place, is that one cannot wire the resistor in the wrong direction. If you do that on the diode, you will permanently damage your printer board.

***UPDATE 2

While I was watching referrals to this blog post I noticed some Swedish(?) web site. When I looked at that blog post (after translation) it showed an ever better way of connecting the sensor to the printer board by using an opto coupler. I know a lot of people don’t have one of these lying around, but if you do… you can’t be any safer. Check it out here.

Microsoft really knows how to get me frustrated

While I was working on a walkthrough on authentication and authorization I decided to use the Microsoft Graph API as an example. In this example I wanted to use application permissions to list all users. Nothing special. Configured my application, wrote some code but… got an error message telling me that my application does not have the required permissions to read all users. So let’s go back to Azure and verify the permissions.

Azure Active Directory Permission Assignment
Azure Active Directory Permission Assignment

Looks pretty good. I actually do have some experience with authentication and authorization – which is why I’m writing this walkthough – but I do not have a clue about what I did wrong. No warning messages here. OK then, let’s search… and GitHub?! contains the answer. It appears that Microsoft decided that besides the permissions given by the administrator, the service principal also needs to be a “Company Administrator” (which you cannot configure from the UI) as a security measure. So the UI is just complete bogus without that role being assigned first. And another hour of my time is down the drain…

UPDATE:
To be consistent with not being consistent Microsoft does allow you to fetch all users if you use the BETA API (https://graph.microsoft.com/beta/users) as security in a public BETA – that is automatically enabled for everyone – apparently is not that important.

Redux…

I have mixed feelings about Redux. I really like the general ideas behind Redux, and how nice they’ve explained how and when to use it. I do not like the implementation however. The main reason for that, is that they invented their own vocabulary around existing design patterns. This distracts you from the patterns they use and that in turn complicates learning.

Why would one call something a “reducer” when it is in fact a “mediator”. Why would you call something an “action” when it is a “command”? The most important Redux framework method is called “dispatch” while it has nothing to do with events. As it invokes a command on the state, it should have been called “invoke” or “invokeCommand”. If they had done a better job on that it would have been clear that we are talking about a basic implementation of the Command pattern.

Another thing I struggle with is that they pass strings around to define which actual commands to execute. Inside the “dispatch” method they call the “reducer” which uses a switch statement to finally invoke the actual required command.

function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

This is very difficult to maintain and almost impossible to refactor. The only good part about it, is that you can easily serialize and store the list of executed “commands” and then deserialize and replay that list on the initial state, to get to the current state. How useful that is, depends on your application. I do think it is at least a bit smelly.

Eventually I decided to create my own predictable state container using TypeScript and standard design patterns.

My own predictable state container

Let’s start with the core.ts:

namespace Core {
    "use strict";

    export interface ICommand<S> {
        execute(state: S): S;
        undo(state: S): S;
    }

    export interface IInvoker<S> {
        invoke(command: ICommand<S>): void;
    }

    export interface IRecorder {
        canUndo: boolean;
        undo(): void;

        canRedo: boolean;
        redo(): void;
    }

    export interface IObservable {
        subscribe(callback: () => void): number;
        unsubscribe(id: number): void;
    }

    export interface IContext<S> {
        state: S;
    }

    interface ISubscription {
        id: number;
        callback: () => void;
    }

    export class Context<S> implements IContext<S>, IInvoker<S>, IObservable  {
        private _state: S;

        constructor(initialState: S) {
            this._state = initialState;
        }

        public get state(): S {
            return this._state;
        }

        protected setState(state: S): void {
            this._state = state;
            this.notify();
        }

        public invoke(command: ICommand<S>): void {
           const state: S = command.execute(this.state);
           this.setState(state);
        }

        private _subscriptionId = 0;
        private _subscriptions: ISubscription[] = [];

        public subscribe(callback: () => void): number {
            const id: number = ++this._subscriptionId;
            this._subscriptions.push({ id: id, callback: callback });
            return id;
        }

        public unsubscribe(id: number): void {
            this._subscriptions = this._subscriptions.filter((value: ISubscription) => {
                return value.id !== id;
            });
        }

        private notify(): void {
            this._subscriptions.forEach((value: ISubscription) => {
                value.callback();
            });
        }
    }

    export class RecordingContext<S> extends Context<S> implements IRecorder {
        private _commands: ICommand<S>[] = [];
        private _current: number = -1;

        constructor(initialState: S) {
            super(initialState);
        }

        public invoke(command: ICommand<S>): void {
            super.invoke(command);
            this._commands.splice(this._current + 1);
            this._current = this._commands.push(command) - 1;
        }

        public get canUndo(): boolean {
            return this._current >= 0;
        }

        public undo(): void {
            if (this.canUndo) {
                const command: ICommand<S> = this._commands[this._current--];
                const state: S = command.undo(this.state);
                this.setState(state);
            }
        }

        public get canRedo(): boolean {
            return this._current < this._commands.length - 1;
        }

        public redo(): void {
            if (this.canRedo) {
                const command: ICommand<S> = this._commands[++this._current];
                const state: S = command.execute(this.state);
                this.setState(state);
            }
        }
    }
}

The core consists of no more than a few interfaces and two generic classes. One class that maintains a list of executed commands, and one that does not. Why I like my implementation better is because I use the same commonly known design patterns, but with the standard vocabulary. Besides that my commands are also passed strongly typed. Which makes it refactorable and maintainable, and prevents you from making typo’s. The drawback is that they are not serializable anymore. Up to you to decide here. Compiled and minified to ECMAScript 6, the whole core takes up no more than 1kb.

Let’s have a look on how to use this core library when we create React.Components in a UI.tsx:

namespace UI {
    "use strict";

    export interface ICounterProps<S> {
        context: Core.Context<S>;
        getValue: (context: Core.Context<S>) => any;
        incrementCommand: Core.ICommand<S>;
        decrementCommand: Core.ICommand<S>;
    }

    export interface ICounterState {
        value: number;
    }

    export class Counter<S> extends React.Component<ICounterProps<S>, ICounterState> {
        private _subscription: number;

        constructor(props: ICounterProps<S>) {
            super(props);
            this.state = {
                value: this.props.getValue(this.props.context)
            };
        }

        public componentDidMount(): void {
            this._subscription = this.props.context.subscribe(() => {
                this.setState({
                    value: this.props.getValue(this.props.context)
                });
            });
        }

        public componentWillUnmount(): void {
            this.props.context.unsubscribe(this._subscription);
        }

        public render(): JSX.Element {
            const buttonStyle: React.CSSProperties = { minWidth: "50px" };
            const {context, incrementCommand, decrementCommand} = this.props;
            const {value} = this.state;

            return (<div>
                Value: {value}
                <div>
                    <button
                        style={buttonStyle}
                        onClick={() => context.invoke(incrementCommand)}>
                        +
                    </button>
                    <button
                        style={buttonStyle}
                        onClick={() => context.invoke(decrementCommand)}>
                        -
                    </button>
                </div>
            </div>);
        }
    }

    export interface IUndoRedoProps {
        context: Core.IRecorder & Core.IObservable;
    }

    export class UndoRedo extends React.Component<IUndoRedoProps, {}> {
        private _subscription: number;

        constructor(props: IUndoRedoProps) {
            super(props);
        }

        public componentDidMount(): void {
            this._subscription = this.props.context.subscribe(() => {
                this.forceUpdate();
            });
        }

        public componentWillUnmount(): void {
            this.props.context.unsubscribe(this._subscription);
        }

        public render(): JSX.Element {
            const buttonStyle: React.CSSProperties = { minWidth: "50px" };
            const {context } = this.props;

            return (<div>
                <button
                    style={buttonStyle}
                    disabled={!context.canUndo}
                    onClick={() => context.undo()}>
                    undo
                    </button>
                <button
                    style={buttonStyle}
                    disabled={!context.canRedo}
                    onClick={() => context.redo()}>
                    redo
                    </button>
            </div>);
        }
    }
}

The important part here is that we pass Core.ICommand<S> for binding to events instead of strings.

So let’s have a look at the App.tsx

namespace App {
    "use strict";

    const update: (value: any, spec: React.UpdateSpec) => any = React.addons.update;

    interface IState {
        number: number;
        char: string;
    }

    class Context extends Core.RecordingContext<IState> {
        constructor() {
            super({ number: 0, char: "a" });
        }
    }

    const Commands = {
        IncrementNumber: {
            execute: (state: IState): IState =>
                update(state, { number: { $set: state.number + 1 } }),
            undo: (state: IState): IState =>
                update(state, { number: { $set: state.number - 1 } })
        },
        DecrementNumber: {
            execute: (state: IState): IState =>
                update(state, { number: { $set: state.number - 1 } }),
            undo: (state: IState): IState =>
                update(state, { number: { $set: state.number + 1 } })
        },
        IncrementChar: {
            execute: (state: IState): IState =>
                update(state, { char: { $set: String.fromCharCode(state.char.charCodeAt(0) + 1) } }),
            undo: (state: IState): IState =>
                update(state, { char: { $set: String.fromCharCode(state.char.charCodeAt(0) - 1) } })
        },
        DecrementChar: {
            execute: (state: IState): IState =>
                update(state, { char: { $set: String.fromCharCode(state.char.charCodeAt(0) - 1) } }),
            undo: (state: IState): IState =>
                update(state, { char: { $set: String.fromCharCode(state.char.charCodeAt(0) + 1) } })
        }
    };

    export function init(): void {
        const root: HTMLElement = document.getElementById("root");
        const context: Context = new Context();

        type Counter = new () => UI.Counter<IState>;
        const Counter: Counter = UI.Counter as Counter;

        ReactDOM.render(<div>
            <Counter
                context={context}
                getValue={(context: Context) => context.state.number}
                incrementCommand={Commands.IncrementNumber}
                decrementCommand={Commands.DecrementNumber} />
            <Counter
                context={context}
                getValue={(context: Context) => context.state.char}
                incrementCommand={Commands.IncrementChar}
                decrementCommand={Commands.DecrementChar} />
            <hr />
            <UI.UndoRedo
                context={context} />
        </div>
            , root
        );
    };
}

window.addEventListener("load", (ev: Event) => {
    App.init();
});

There are a lot of way’s to define commands now. In the above example I’ve created a const Commands object that contains the command objects as I do not need any per command state or properties. You could of course do something like this to define a custom command just as well:

class CustomIncrementCommand implements Core.ICommand<IState> {
    private properties:ICustomIncrementCommandProps;
    constructor(properties: ICustomIncrementCommandProps) {
        this.properties = properties;
    }

    public execute(state: IState): IState {
        return update(state, { number: { $set: state.number + properties.incrementValue} });
    }

    public undo(state: IState): IState {
        return update(state, { number: { $set: state.number - properties.incrementValue} });
    }
}

You could then pass the constructor to your components and in the component itself, create a new instance of the command, with the properties based on the current component state.

All in all we now have a complete, generic, strongly typed predictable state container using TypeScript and standard design patterns, that also uses the proper vocabulary.

UPDATE:
That same friend asked me if he should now use my implementation of a predictable state container or the standard Redux implementation. That should be the Redux implementation of course! There are a lot of people working on maintaining Redux and there are a lot of (browser)plugins that you can use with the standard Redux implementation. The value of Redux is not just in Redux itself, but also the eco-system around it. The reason I wrote this article and a sample on how I would do it, is just because I think that if they’d at least adhered to the standard design patterns, it would have been a lot easier to learn how to use Redux.

Have fun,

Wesley