Tuesday, December 6, 2016

CT Sensor on AVR ATmega

-- ref. 2012

A CT (Current Transformers) sensor is a device used to measure alternating current.
A CT sensor, like other current transformers is made by a primary winding, a magnetic core and a secondary winding. The primary winding is often a single wire passing through the main core of the transformer. The seconday winding is used to sense the AC current passing through the primary winding wire. They are usually build to be clipped on the primary wire. As any other AC transformer the primary winding current produce a change in the magnetic field of the core. This change cause current on the secondary winding.


This library implements a way to read current using a CT sensor on ATmega.
It performs an RMS read on ADC, then computes the RMS voltage on ADC input.
So the primary current Ip is calculated by using the formula

Ip = V * Ns / Rburden

Given
Ns = Turns on secondary coil, i.e. the CT sensor core turns
Rburden = Burden resistor of the CT sensor.


Below some tips on how the CT sensor works, and how to find an appropriate value for the burden resistore.

Given
Vp = Voltage on primary
Vs = Voltage on secondary
Np = Turns on primary
Ns = Turns on secondary
Ip = Current on primary
Is = Current on seconday
CTratio = Np / Ns

From the Faraday's Law
Vs/Vp = Ns/Np

And, due to conservation of energy
Vp*Ip = Vs*Is

So
Vp = (Np/Ns)*Vs
and
Vp = (Vs*Is)/Ip
Then
CTratio*Vs = (Vs*Is)/Ip

Simplified:

Is = Ip * CTratio

Using the ADC of our microcontroller we can read voltages, so we need to "convert" the current output of the CT sensor to voltage. We can doing this using a resistor, the burden resistor.

To calculate the burder resistor value we need a few information.

We need to know the current range of our CT sensor, let's call this Imax.
Then then number of turn on secondary (Ns).
Then the ADC reference voltage, usually 5V on ATmega (AREF)

We have to select a burden resistor that products the voltage we want. In our case, we would like to product a voltage equals to AREF/2

So
Rburden = (AREF/2) / Isp

Given
Isp = Peak current on secondary
Ipp = Peak current on primary
Np = 1

We also know that
Isp*Ns = Ipp*Np
so
Isp = (Ipp*Np) / Ns

Now we can convert RMS Ip to Peak to peak current
Ipp = sqrt(2) * Ip
And
Isp = (sqrt(2) * Ip) / Ns

Simplified:

Rburden = (AREF*Ns) / (2*sqrt(2)*Imax)

Below the schematics used on the ATmega sample.
Notice the two biasing 10k resistors.


Code
Notes
  • read risk disclaimer
  • excuse my bad english


Tuesday, November 15, 2016

ABService, a .NET Windows Service Application helper

ABService is a .NET Windows Service Application helper.


Microsoft Windows services, formerly known as NT services, enable you to create long-running executable applications that run in their own Windows sessions. These services can be automatically started when the computer boots, can be paused and restarted, and do not show any user interface.

ABService is part of the AvioBrain project. This is the first library with an open-source license from AvioBrain.

In order to build a Windows Service Application on .NET and Visual Studio you have to create a Windows Service project.
Then you have to implement the main ServiceBase class overriding at least the OnStart and OnStop methods.
The OnStart is the method triggered when the service starts up, OnStop is triggered when the service is been request to stop.
You can also add a class that implements the service Installer. This will gives you the opportunity to simplify the install process of your service.

This library extends the ServiceBase and Installer class and lets the user just write the worker part of the service.

It offers a console mode, that can be started using the --run arguments.
The install process it's been triggered by the --install command, this will install the service on your machine.
The --uninstall command will auto-remove the service.

The ABService core, runs a timer every second, although the timer interval can be changed in code.
The main timer will check if the service worker function is running, if not, it will start the user worker method.

The sample project will show how to use this library in your service.
In a few step, the user will:
  1. Build up the custom worker method, it could be as simple as a void Do() method inside a class.
  2. Edit the Program.cs main file. This will start the ABService runner
  3. Edit the main windows service item, extending the ABService one. Here is where we set up the main check timer, and the worker method.
  4. Edit the service installer class, extendint the ABService one. This will implements all the install/uninstall features.

Code & Binary

Notes
  • read risk disclaimer
  • excuse my bad english

Saturday, October 8, 2016

DGUIGHF a UI GUI Helper Framework built for .NET WinForm

DGUIGHF is a UI GUI Helper Framework built for .NET WinForm.


The purpose of DGUIGHF is to simplify the building of desktop .NET applications.
It expose a few methods that helps the developer to write less code to mantain the UI of a desktop application.
The idea is to provide an helper to handle the windows status.
Each form of a "standard" application had a list of elements (a DataGridView) and a component to perform CRUD operations on items (a TabControl).
The main list it is binded to a view BindingSource, the CRUD handler it is binded to the database referenced BindingSource.
Whenever a list object is selected, the database BindingSource it is updated, and so the CRUD handler components.
To use this helper, you have just to extend your System.Windows.Forms.Form to DGUIGHFForm.
The key point is to extend to override the InitializeTabElements method to attach the components of your custom form.
Each CRUD handler it's called a TabElement.
There are a few TabElement available. Two of them are the most important, one to attach the components to the parent list, one to attach a list of items and a child TabElement for that list.
Each TabElement can have child TabElements, that way it will be simple to build up a tree of CRUD handler on a single page.
The image below shows a TabElement tree.


When the user perform an operation on a TabElement, the other tab can be locked, this way, the BindingSource will not change due to other data changing.
The code is provided with a sample that exhibit the main TabElement available.
The best place to learn how to use this framework is the Sample project.
There are Data helper to handle operations of the database.
This helper makes uses of the DGDataModel, a generic C# data access layer built on top of the Entity Framework.
There is also a Language helper that perform internationalization operation on each Form component.
As example, building up a simple CRUD Form will take just a few lines of code.
Given a model for a simple "Tag" element that extends the DGDataModel, the following code will handle all the CRUD operation on that.

public partial class FormTags : DGUIGHFForm
{
 private DGUIGHFSampleModel samplemodel = null;
 private TabElement tabElement_tabTags = new TabElement();

 public FormTags()
 {
  InitializeComponent();

  Initialize(Program.uighfApplication);

  samplemodel = new DGUIGHFSampleModel();
  samplemodel.LanguageHelper.LoadFromFile(Program.uighfApplication.LanguageFilename);
 }

 protected override void InitializeTabElements()
 {
  //set sort on View bindingSource
  vTagsBindingSource.Sort = "name";

  //set Readonly OnSetEditingMode for Controls
  DisableReadonlyCheckOnSetEditingModeControlCollection.Add(typeof(DataGridView));

  //set Main BindingSource
  BindingSourceMain = vTagsBindingSource;
  GetDataSourceMain = GetDataSource_main;

  //set Main TabControl
  TabControlMain = tabControl_main;

  //set Main Panels
  PanelFiltersMain = null;
  PanelListMain = panel_list;
  PanelsExtraMain = null;

  //set tabTags
  tabElement_tabTags = new TabElement()
  {
   TabPageElement = tabPage_tabTags,
   ElementItem = new TabElement.TabElementItem()
   {
    PanelData = panel_tabTags_data,
    PanelActions = panel_tabTags_actions,
    PanelUpdates = panel_tabTags_updates,

    ParentBindingSourceList = vTagsBindingSource,
    GetParentDataSourceList = GetDataSource_main,

    BindingSourceEdit = tagsBindingSource,
    GetDataSourceEdit = GetDataSourceEdit_tabTags,
    AfterSaveAction = AfterSaveAction_tabTags,

    AddButton = button_tabTags_new,
    UpdateButton = button_tabTags_edit,
    RemoveButton = button_tabTags_delete,
    SaveButton = button_tabTags_save,
    CancelButton = button_tabTags_cancel,

    Add = Add_tabTags,
    Update = Update_tabTags,
    Remove = Remove_tabTags
   }
  };

  //set Elements
  TabElements.Add(tabElement_tabTags);
 }

 private void FormTags_Load(object sender, EventArgs e)
 {
  ReloadView();
 }

 private object GetDataSource_main()
 {
  IEnumerable<VTags> vTags =
   samplemodel.Tags.List().Select(
   r => new VTags
   {
    tags_id = r.tags_id,
    name = r.tags_name
   }).ToList();

  return DGDataTableUtils.ToDataTable<VTags>(vTags);
 }

 private object GetDataSourceEdit_tabTags()
 {
  return DGUIGHFData.LoadEntityFromCurrentBindingSource<tags, DGUIGHFSampleModel>(samplemodel.Tags, vTagsBindingSource, new string[] { "tags_id" });
 }

 private void AfterSaveAction_tabTags(object item)
 {
  DGUIGHFData.SetBindingSourcePosition<tags, DGUIGHFSampleModel>(samplemodel.Tags, item, vTagsBindingSource);
 }

 private void Add_tabTags(object item)
 {
  DGUIGHFData.Add<tags, DGUIGHFSampleModel>(samplemodel.Tags, item);
 }

 private void Update_tabTags(object item)
 {
  DGUIGHFData.Update<tags, DGUIGHFSampleModel>(samplemodel.Tags, item);
 }

 private void Remove_tabTags(object item)
 {
  DGUIGHFData.Remove<tags, DGUIGHFSampleModel>(samplemodel.Tags, item);
 }
}

Find the hanlded form below:


Code & Binary

Notes
  • read risk disclaimer
  • excuse my bad english

Friday, September 9, 2016

DGSerial: a serial port library for .NET

DGSerial is a serial port library for .NET.


It's a wrapper built on top of System.IO.Ports.SerialPort class. It adds some usefull methods to the default .NET library.
Some of them are the:
  • ReadBytes with a timeout
  • ReadBytesTo read until a byte, with an esape byte function and eventually a timeout
  • WriteBytes with timeout
Also a few Helpers are priveded like:

  • CRC8721, a CRC poly X^8 + X^7 + X^2 + 1 builder, for which there's also the ANSI C code
  • String to Byte and Byte to String methods

It is really a simple library.


Code & Binary

Notes
  • read risk disclaimer
  • excuse my bad english

Wednesday, August 3, 2016

An AVR Atmega library for multiple HD44780 based LCD connected through i2c



This library implements a driver for HD44780 lcd connected through PCF8574 port expander.
Data is transmitted using only 2 wire over i2c with the PCF8574.
This library can drive up to 8 LCD concurrently.


Lcd driver is based upon Peter Fleury's lcd driver
HD44780 to i2c library its based upon this library: http://davidegironi.blogspot.it/2013/06/an-avr-atmega-library-for-hd44780-based.html

Each PCF8574 needs to have a different address selected, this can be done by the A0,A1 and A2 pins.


Setup parameters can be found in file lcdpcf8574.h and pcf8574.h
This library was developed on Eclipse, built with avr-gcc on Atmega8 @ 8MHz.


Code
Notes
  • read risk disclaimer
  • excuse my bad english

Saturday, July 9, 2016

Joyo Vintage Overdrive mod - Tube Screamer clone


The Joyo Vintage Overdrive JF-01 is a Tube Screamer guitar pedal clone.


I've checked it against the TS-808 Tube Screamer schematic, and what I've found is that it has the circuit, it also has the same components values of the Tube Screamer.
Indeed, at least to my ear, it's sounds like a TS-808.


But, because i would like to experiment a little, i apply some mod on this pedal.
I've basically given a little more distorsion to the pedal. I also add a "Fat" switch, to makes it sounds fatter, and I've replaced the two clipping diode with two 5mm IR leds. Also I've changed two electrolitics caps of this pedal with two film caps.


Below you can find my schematics.




I would like to thank my friend "Bond" that lends me his Tube Screamer clones, which I've used as reference in addition to a genuine TS-808 by Ibanez.

Notes
  • read risk disclaimer
  • excuse my bad english

Thursday, June 2, 2016

A CNC Pickup Winding machine built on an ATmega8


A pickup winding machine it is used to wind a guitar pickup.
You can find my previous ATmega manual pickup winding machine here: http://davidegironi.blogspot.it/2014/05/a-pickup-winding-machine-built-on.html
This project is a manual / CNC pickup winding machine, built on top of an ATmega8 microcontroller.


Characteristics:
  • wind counter
  • slow startup
  • automatic stop
  • configurable motor speed
  • configurable winds
  • 2 direction
  • CNC automation
  • configurable wire dimension (for CNC)
  • traverse dynamic speed
This winder has an LCD display, it will show:
  • the current motor direction
  • the rotating speed of your pickup
  • the total and current wind counter
  • the direction of the traverse mechanism
  • the speed of the traverse motor
User can choose if enable or not the guide movement, if not, this machine can be use in manual mode.

There are 3 buttons, SELECT, button UP and DOWN.
Short press SELECT to move to make the traverse motor move 1mm.
Long press SELECT to enter / exit programming mode. During the programming mode press button UP and DOWN to edit the selected value, short press SELECT to skip the next value, or long press SELECT to save new values and go back to running mode.
Short press button UP to change direction of the winding.
Long press button UP to reset counter.
Short press button UP to change direction of the guide movement.
Long press button DOWN to reset counter.


If you are in building mode, to make the wind start press the RUN pedal, it will start with a slow startup, to stop the winder release the RUN pedal.

The winding machine will automatically stops when the wind counter reach the configured number.
If you disable the autostop mode, the machine will always count wind, independently by the direction choosen.

The winding motor used is cheap DC motor 12V 1200rpm, the motor driver is L298N chip board.


The traverse mechanism it is built using parts from a (broken) scanner, the guide motor is the stepper motor of the scanner.


Traverse mechanism has two limits. Limits are build using break-beam optosensos mounted on a small cilindric neodymium magnet.
That way guide limits can be moved depending on the pickup to be wired.


The wire tensioner it build using felts and a spring. It is simple but it works quite good.

The winding nozzle it's taken apart from a dental saliva ejector that my father (who is a dentist), gives me. It has a really small hole, and it's also built with plastic. This will not damage the wire we are going to wind.


The counter sensor it is built using a hall effect switch and a small neodymium magnet glued to the pickup holder.

My traverse mechanism has an accuracy of 5.29 um/step. One can mount another guide motor and harware, and will have other accuracy, indeed that mechine need to be calibrated.

Whenever the guide mechanism is changed, those constants has to be set GUIDEMOTOR_1STEPUM, GUIDEMOTOR_1MMSTEP, GUIDEMOTOR_1CMMAXSPEEDTIMEMS, GUIDEMOTOR_1CMMINSPEEDTIMEMS, GUIDEMOTOR_FIXEDSPEED_DEFAULT, WIRE_MINGAUGE, WIRE_MAXGAUGE

There are two calibration steps the user has to do:
  1. Measure the traverse distance moved per step. The GUIDEMOTOR_MEASURESTEP directive has to be set to 1, and the number of step to move has to be set in GUIDEMOTOR_MEASURESTEPSTEPS. Then the hex has to be compiled and uploaded. Now when you startup the machine, the guide will move for the desired number of steps. We measure the distance traveled. We compute the steps/mm as steps moved / total distance traveled. Than um/step is 1000 / steps/mm. Let's suppose we have set 20000 as step to move. If we have measured a traveled distance of 106mm, the step/mm is 188.879, and um/step is 1000/188.879, so 5.29. When done, set GUIDEMOTOR_MEASURESTEP to 0 again. Now we can set GUIDEMOTOR_1MMSTEP to step/mm value and GUIDEMOTOR_1STEPUM to um/step value.
  2. Measure the traverse maximum / minimum speed. The GUIDEMOTOR_MEASURESPEED directive has to be set to 1. Then the hex has to be compiled and uploaded. Now when you startup the machine, the LCD will show the max and min speed the guide motor takes to move 1cm. When done, set GUIDEMOTOR_MEASURESPEED to 0 again. Now we can set GUIDEMOTOR_1CMMAXSPEEDTIMEMS and GUIDEMOTOR_1CMMINSPEEDTIMEMS to the values shown on the display.
After that calibration steps is been execute, other values has to be set.
A guide step helper spreadsheet it is provided to help compute that values. The GUIDEMOTOR_FIXEDSPEED_DEFAULT, WIRE_MINGAUGE and WIRE_MAXGAUGE dimensions can be computed using this sheet.
You just has to fill values you already know, the values of your hardware.

The math to compute that values is also described as comments in the source files.

The maximum and minimum wire gauge it is an important parameter that defines what your pickup winder can wrap.

The winding pattern implement in this machine, is a simple traverse winding that places each wire wind next to the previous one.
See below and example of a pickup winded with this machine.


Things get's intereseting here, because the wiring motor doesn't always spin the same speed, take as example the "slow startup" stage, or when you decide to wire your pickup at a lower speed.

The guide motor is driven in a TIMER interrupt.
Here we set the steps that motor walk to position the cable,
We know:
  • the number winds made from the last motor movement
  • the current pickup rotation speed
  • the wire gauge
  • how many distance the guide motor travel for every step done
  • the maximum and minimum time the guide motor takes to walk 1cm

We can compute how much space the traverse mechanism has to travel in order to place the wire next to the previus one, that's pretty simple.

number_of_winds = current_number_of_winds - current_number_of_winds
distance_to_wire = wire_gauge * number_of_winds
step_to_move = distance_to_wire / guide_motor_distance_traveled_for_1_step

Things get's a little complicated because i'm not using float math, so i've to record the remnant of the division.

number_of_winds =
  current_number_of_winds - current_number_of_winds
distance(um)_to_wire =
  wire_gauge(um) * number_of_winds + remntant_distance(um)_to_wire
step_to_move =
  distance(um)_to_wire / guide_motor_distance(um)_traveled_for_1_step
remntant_distance(um)_to_wire =
  distance(um)_to_wire % guide_motor_distance(um)_traveled_for_1_step

But that's not all folks, we also have to move the guide motor at such a speed that every wire is placed next to the other right when the pickup has done a full loop, I mean, we do not want a rapid guide motor travel, then a motor stop, then a rapid travel again, that movement has to be continous, and smooth, related to the pickup winding speed.

So, let's try to estimate that guide motor speed.

rotation_per_seconds = motor_rpm / 60
distance(um)_to_wire_in_1second = rotation_per_seconds * wire_gauge(um);
time(ms)_to_wire_1cm = (10000*1000) / distance(um)_to_wire_in_1second;

Now, the trick here it that we have previously recorded the maximum and minimum time in ms that the guide motor takes to move 1cm, so we can map the time we need, with that max and min speed.

speed = 100 - (time(ms)_to_wire_1cm - GUIDEMOTOR_1CMMAXSPEEDTIMEMS) * (100 - 1) / (GUIDEMOTOR_1CMMINSPEEDTIMEMS - GUIDEMOTOR_1CMMAXSPEEDTIMEMS) + 1;

That way we obtain a speed value from 1 to 100 for the guide motor to run smooth.

Enabling GUIDEMOTOR_DEBUGSTEPANDSPEED will display the current speed and steps left to run for the guide motor. This is a usefull during the debug stage. The speed will never exceed 100, and the steps left will never grow up. It it happens, it means that the guide is going too slow.


Future improvements will be implement an UART protocol to drive this machine by a PC, that way multiple wiring pattern can be simply performed.

This project was developed on Eclipse, built with avr-gcc on ATmega8 @ 16MHz.


Code

Notes
  • read risk disclaimer
  • excuse my bad english

Friday, May 6, 2016

DigiTech MC7 MIDI Controller Pedal repair

The DigiTech MC-7 MIDI Controller Pedal is a standard MIDI program change device.


The MC-7 transmits 1-128 program changes on 1-16 MIDI channels.
I've buy this JUN'91 pedal used for a few Euros. It has a problem on the "c" segment of any of the four 7-segment display.
The repair was quite simple. The integrated 7-segment display lines are driven by  through a 74HC574 octal D-type flip-flops. Signal goes by the 74HC574 through 8 resistors in the 7-segment display.


It takes a few minutes to find which was the "c" segment output signal, simply changing the output channel to display or not that line. Once i've done it, i've checked if the signal goes in to the display... and BINGO!... for the "c" signal it get's interrupted on the soldered join of the display. It's the last join on the right of the below picture.


I just soldered it back, and the display keep working. As you can see.
Pretty simple.
Just for those you are interested, that's the refresh timing for that display.


Adding a cheap USB to MIDI adaptor gives this '91 pedals takes this pedal "Back to the Future".

Thank for Paolo that sells me this pedal board, and a thumbs up to DigiTech support that sends me the 4 pages manual for this pedal, just for completeness.


Notes
  • read risk disclaimer
  • excuse my bad english


Friday, April 1, 2016

Behringer v-tone GMX212 Hybrid tube amplifier mod


Some time ago I've repaired a Behringer v-tone GMX212 http://davidegironi.blogspot.it/2012/01/behringer-v-tone-gmx212-repair-bypass.html
That was the first post of this blog.

Now I would like to mod this amplifier, switching is original preamplifier board with a custom one.
This mods dives me in the vacuum tube world.

WARNING! - The project described in these pages utilizes POTENTIALLY FATAL HIGH VOLTAGES. Do not attempt to build circuits presented on this site if you do not have the required experience and skills to work with such voltages. I assume no responsibility whatsoever for any damage caused by the usage of my circuits.


To improve my knowledge on tube amplifiers, I've read articles from two really well written website: http://www.valvewizard.co.uk/ and from http://www.ax84.com/.

For this project I've used 12AX7 vacuum tube. This tube is one of the most used for the guitar preamplification. So there are many resources available on web.
The first problem i faced it's the power stage. Tubes needs high voltage in order to work properly. The solution I've found was to connect a 230V/9V power transformer with secondary and primary reversed. That way, connecting it to the 10.5V AC output of the main Behringer transformer i can get almost 160V DC.
Any tube also needs a low voltage current to power up the heater. I choose to use a 7805 voltage regulator, shifted by 1.3 volts using two switching diodes. This gives me the 6.3V DC I need.


The preamplifier circuit it's next to the AX84 P1 Guitar Amplifier, the tube load and ground resistor where changed to fit the load line of my tube for my power voltage. You have to calculate your own values it you use other voltage.
As a tone circuit, I've selected something similar to the Fender Tweed Princeton one.


The Behringer v-tone GMX212 has many output and input on the back that i do not want to lose.
To keep the back ports and to reach the amplifier board with correct voltage, I've built a connection boards that levels the preamplifier input like the original Behringer preamplifier board does.
I've just measured levels coming out from the original board, and reproduced my version of that circuit using two TL072 opamps to adapt my preamplifier levels.


Eventually I would like to add some sort of reverb effect to this amplifier. So I've try the PT2399. What I've built it isn't really a reverb, it's more an Echo/Delay. But it's an interesting ambient effect i would like to have on this amplifier.
The reverb board use on TL072 to mix the wet and dry signal without any lose.


The amplifier stage is the original Behringer v-tone GMX212 one.

The amplifier plate log was replaced by a new one, engraved with my homemade laser engraving machine: http://davidegironi.blogspot.it/2015/12/a-diy-a4-laser-engraver-made-from.html


That's all for this amplifier... until the next modification.

12AX7 guitar preamplifier and power supply board:


Schematics of the PT2399 delay/reverb board:


Schematics of the mix level board:



Updates
  • The single knob tone control has been updated on 2018/12/22. Now it is based on the Supro Thunderbolt

Notes
  • read risk disclaimer
  • excuse my bad english

Monday, March 7, 2016

A generic C# data access layer built on top of the Entity Framework

The Entity Framework is the Microsoft official ORM (Object-Relational Mapping) framework.


This library implements the Repository Pattern. It's mask the detail of the Data Access Logic from the Business Logic using Repositories.
Repositories are build on top of Entities using C# generics.
Repositories offers a few methods to perform CRUD operations (Create, Read, Update, Delete) and other SQL operations like MAX, MIN...
An instance of the entity framewor context class is created for each operation.
Each repository implements an interface that provides methods to performs operation on an entity object of the model.
You can access any repository by the main model instance. Each repository will be instantiated at the model construction.
Any repository method can be overriden.
The main model class implements the a generic class and defines each repository as a public property.

The main methods you will find on repository are:
  • List: load an entities with records
  • Find: load an entities searching for key values
  • Add: add records to the underlying database
  • Update: update records of the underlying database
  • Remove: remove records from the underlying database
The List method filter values by the use of a predicate.
The generated LINQ query is then translated to SQL by the Entity Framework engine.
The Find method implements the Find LINQ method.
Add, Update and Remove methods perform the SQL INSERT, UPDATE and DELETE operations.

Three methods should be overridden almost every time a Repository is implemented:
  • CanAdd: check if entities can be added
  • CanUpdate: check if entities can be updated
  • CanRemove: check if entities can be removed
Those methods should be called before the main Add, Update and Remove operations to check for entites consistency.

Other SQL/LINQ operators are implemented in the repository, like:
Any, FirstOrDefault, Average, Order, Count, LongCount, Max, Min, Remove, Sum.

A LanguageHelper class provides usefull methods to internationalize String fields used in repositories. Those fields can be used to localize errors message for repository methods.

A few lines of codes are enough to implemt a fully loaded model.

This project is as always release open source. You can find source code, on the github.com link above.
The code also contains a sample model, and a few UnitTest to check against it.


Code

Notes
  • read risk disclaimer
  • excuse my bad english

Sunday, February 14, 2016

EnhancedBoxHelper .NET WinForm component helper

EnhancedBoxHelper is a open source enhanced component helper for .NET WinForm.



It's adds some advanced functions to an existing componente:
  • ComboBox
  • TextBox
  • DateTimePicker
by using the generetor helper.

It requires Microsoft Windows with .NET framework 4.0 or more.

It's basically a static class helper, that attaches events to a component.

One a TextBox you could attach the
  • Deselect on ESC press function: cleans the component if ESC key is pressed
  • Show the Helper form on Right click: show a popup form that lists a bounce of preselected values for the component
  • Show a Tooptip on Mouse Over: show a Tooltip that informs the user about the data selected
The ComboBox also has the
  • Deselect on ESC press function: cleans the component if ESC key is pressed
  • Show the Helper form on Right click: show a popup form that lists a bounce of preselected values for the component
  • Autocomplete on ENTER press function: autocomplete the selected item if ENTER key is pressed
  • Show a Tooptip on Mouse Over: show a Tooltip that informs the user about the data selected
DateTimePicker enhanchments includes :
  • Fast Select Key:
    • Press n or N to set now datetime
    • Press t or T or d or D to set today date
    • Press w or W to set the first, or last day of the week
    • Press m or N to set the first, or last day of the month
    • Press y or Y to set the first, o last day of the year
  • Move to the next datepart on / (slash) press
  • Interval helper on date selector. By setting a interval helper between two DateTimePicker, the user can select range of dates using some helpfull shortcut, or a combobox helper. The combobox attached to the helper can contains values that comply with the %d[d|w|m|y] regex. %d is a number, d stands for days, w for weeks, m for months, y for years. As example, if "+1d" is selected the To picker will be set as From +1 day, if "+2w" is selected the To picker will be set as From +2 weeks, and so on. A maximum interval number can be setted, so that the two pickers can never exceed that interval time. The date To select react to date From by custom fast keys:
    • Press CTRL + d or D on the From component will set the To to the same day of the From
    • Press CTRL + w or W on the From component will set the To to +1 week from the From
    • Press CTRL + m or M on the From component will set the To to +1 month from the From
    • Press CTRL + y or Y on the From component will set the To to +1 year from the From
The popup form uses the AdvancedDataGridView component you could find here.
Two small line are printed on the top right corner of any component attached by the autocomplete helper windows. The color of the two lines can be overriden on the static class.

The most of the time one should attach all the helper provied.
Using the attacher helper method is quite simple, you can find a few example in the sample project and a little sample snippets below.

//Sample attachment function
EnhancedComboBoxHelper.AttachComboBox(
  comboBox1,                                    //target component
  new string[] { "Name", "Address" },           //header for autocomplete Form
  _users.ToList().OrderBy(r => r.name).Select(  //load the list for autocomplete Form
    r => new EnhancedComboBoxHelper.Items()
    {
      _id = r.id,                               //id of selection
      _value = r.name,                          //show value
      _values = new string[]                    //values listed
      {
        r.name,
        r.address
      }
     }).ToArray());

//Sample attachment function
EnhancedComboBoxHelper.AttachComboBox(
  comboBox1,                                    //target component
  new string[] { "Name", "Address" },           //header for autocomplete Form
  _users.ToList().OrderBy(r => r.name).Select(  //load the list for autocomplete Form
    r => new EnhancedComboBoxHelper.Items()
    {
      _id = r.id,                               //id of selection
      _value = r.name,                          //show value
      _values = new string[]                    //values listed
      {
        r.name,
        r.address
      }
   }).ToArray(),
   EnhancedComboBoxHelperList.ViewMode.SelectOnDoubleClick,    //selection mode, how the autcomplete Form selection changes is treated
   () => MessageBox.Show(comboBox2.SelectedValue.ToString())); //selection mode action, get's called after the selection on the autcomplete Form changes 

//Sample attachment function
EnhancedDateTimePickerHelper.AttachDateTimePicker(
  dateTimePicker1,                              //target component
  "yyyy/MM/dd");                                //custom format

//Sample attachment function
new EnhancedDateTimePickerHelper.FilterDateHelper(
  dateTimePicker2,                              //target component from
  dateTimePicker3,                              //target component to
  null,                                         //actions to run after the date is changed
  comboBox3,                                    //fast day combobox selector
  365,                                          //max days between from and to date
  DayOfWeek.Monday,                             //first day of the week
  EnhancedDateTimePickerHelper.FilterDateHelper.FromPickerDefaultValue.FirstDayOfWeek,    //select the default day for from datetimepicker
  EnhancedDateTimePickerHelper.FilterDateHelper.ToPickerDefaultValue.FromPickerSameDay);  //select the default day for to datetimepicker



Code

Notes
  • read risk disclaimer
  • excuse my bad english

Saturday, January 9, 2016

A Xively trigger PHP script to send email and SMS notifications

Xively is a platform devoted to simplifying the interconnection of devices and data with applications on the Internet of Things.


It uses feed and channels to collect user data. Any Xively channel can have one or more triggers. A trigger is a notification sent when a condition occurs on that channel.
For example if a channel is related to temperature. One can add a notification triggered when the temperature goes below a ceratin threshold.
Xively trigger does an HTTP POST request to an URL.
This is a PHP script one can use to send email and/or SMS alert for a Xively feed trigger action.

To use this script you have to upload it to any website running a PHP server.
Email are sent using the PHP mail function.
SMS are sent through a Betamax/Dellmont Voip provider. So, in order to be able to send SMS you must have some Dellmont voip account, and fill your credetils in the configuration zone of this script.
To prevent the notification of many SMS, a limiter functionality is implemented.
Also a sign it is used as a token to allow only the ones who know the token to use the script.

To use this script, point the Xively channel trigger post url to this script, and set the url parameter for your message.
As example, suppose you have installed the script at this address:
http://example.com/xivelytrig/xivelytrig.php
To send both mail and sms, use this url:
http://example.com/xivelytrig/xivelytrig.php?sign=example.com/xivelytrig/xivelytrig.php?sign=123456&feed=your_feed_name&channel=your_channel_name&alarm=your_alarm_text&address=address@example.com&mobile=000000000000
To send just email use this:
http://example.com/xivelytrig/xivelytrig.php?sign=example.com/xivelytrig/xivelytrig.php?sign=123456&feed=your_feed_name&channel=your_channel_name&alarm=your_alarm_text&address=address@example.com
Replace
 - 123456 with the $sign you set in your script
 - your_feed_name with then feed name you want to get for the notification
 - your_channel_name with then channel name you want to get for the notification
 - your_alarm_text with then message you want to get for the notification
 - address=address@example.com with the mail where to send the notification
 - 000000000000 with the mobile number where to send the notification


Code

Notes
  • read risk disclaimer
  • excuse my bad english