text:
Coin Acceptor CH-925 Pulse
I got a problem where pulse voltage from acceptor is about 20mV. How can I solve my problem? and I can't detect the pulse using arduino uno.
please any one can help ?

Output seems kind of low... Are you powering it with +12 volts?

yes I power it with +12v adapter and 1 A , it is a big problem to me since that this module doesn't exist in my country , and I wait 1 month to got it .Is their any solution?

I don't know- it just seems odd that the output voltage is 20mv. I think you've either miswired it or you have a defective unit. Check the documentation to see what output voltage you should expect.

I'm now trying to amplify this value to 5V Is this right ? or I must buy another one ?

From this Amazon review:

There are 'live' (12V), 'ground' and 'signal' wires coming out of the
  back. Live and ground are pretty self-explanatory, and need to be
  connected to a 12V supply - I bought a simple 1A DC one. The final
  wire says 'signal', and needs to be connected to your circuit as input
  into a GPIO pin in the case of a raspberry pi. It produces a pulsing
  5V signal (Why not tell us it will be 5V somewhere in the
  documentation? Luckily I have a multimeter) as a way of encoding which
  type of coin it has encountered. However, raspberry pi's only want
  3.3V signals as inputs, so you'll be wanting to make a voltage divider (With a couple of resistors - I used 33k and 18k) to safely bring that
  5V pulse down to 3.3V. (http://en.wikipedia.org/wiki/Voltage_divider)
  You'll also want to connect the ground from the device to a ground on
  your Raspberry Pi, or the signal won't work. I did this by splicing
  the ground cable from the power supply so that it has 2 ends - 1 for
  the power supply to the unit, and one for the unit to the Raspberry Pi
  Circuit.

It seems that a 5v pulse is the expected output. How are you measuring the output? You'll need a 'scope rather than a multimeter measuring voltage...
Anyway, I would not try to 'amplify' the signal, I would look to check the connections are correct and if that's not the issue, I would return the unit as defective.

I wonder if the output is actually an "open collector" type that needs a pull up resistor to 5V before you see a proper pulse. Pull-ups can be configured on the AVR input pins - which the Amazon reviewer may have done on his GPIO pin - or an external resistor could be used. Regards,

good point @Michael Vincent +1

I connected the signal to an arduino and programmed the unit  just like the videos in YouTube, the arduino cant read the signal, then I tried to detect the signal using oscilloscope, I spent 1 week on trying many solutions all of them failed, then the last thing I'm going to do is to amplify the value to 5 V, I'm wondering if their is any possible solution !

what do you mean with "scope"  You'll need a 'scope rather than a multimeter measuring voltage... ?

and the big problem is that this unit isn't available in my country and I waited about one month to get it form outside!! and bringing anther one will be time consuming .

Make sure you're looking at the signal reference the power supply ground. If your ground is floating then you won't see anything (or 20mv). If you have three wires- 12v, Gnd, and Signal, then you also need to connect the power supply ground to the arduino in order to see any signal out of the coin acceptor. Check this by connecting your meter ground to the power supply ground, and your meter + to the signal out.

Correction... Use your scope, not a meter. The coin value encoding is a pulse train (I gather) and you may not see it correctly with a meter.

I checked all connections and they are as you said, I connected the signal wire (white wire ) to analog input 0 (A0) and I read the value , it is about 7 when nothing is inserted and it's 27 when a coin is inserted ! I tried to fix the problem in code , but unfortunately all this doesn't seem to work !  what to do in this case ? Is it good option to amplify the value to 5v ?

authors: محمود عبد الكريم


text:
How to use "+" character as a String
Well I am trying to save phone number as a string. For ease of use I want to add "+" character programmatically. Like this:
String cepNo ="+" + "901234567";

But program gives this error.
exit status 1
invalid operands of types 'const char [2]' and 'const char [13]' to binary 'operator+'

How to add "+" beginning of the string.

A string literal isn't a String. You can't concatenate them like that. This is C, not BASIC.

The arduino error is on the +, not the "+".

You cannot add C strings (i.e. NUL-terminated arrays of char) with the
+ operator. It only works with String objects. You can, though, add
a String object and a C-string, because in this case the compiler
implicitly converts the C string into a String object:
String phone_number = "901234567";
phone_number = "+" + phone_number;

The last line is interpreted by the compiler as
phone_number = String("+") + phone_number;

That being said, I encourage you to try to avoid String objects if
possible. These use dynamic memory allocation which carries the risk of
heap fragmentation. The same thing can be achieved with plain C strings:
char phone_number[] = "901234567";
char full_phone_number[strlen(phone_number) + 2];
strcpy(full_phone_number, "+");
strcat(full_phone_number, phone_number);

Note the size of the second string: strlen(phone_number) + 2. You need
one extra char for the + sign, and another one for the NUL string
terminator.
Now, with C strings you can do better, and avoid copying: reserve enough
room in an array for the full number (“+” included), and then fill the
digits starting from the second slot in the char array. You can then
add the + sign later:
char phone_number[16];
strcpy(phone_number + 1, "901234567");
phone_number[0] = '+';

Although I personally would write the “+” sign and a NUL while
initializing the array:
char phone_number[16] = "+";
strcat(phone_number, "901234567");

use String cepNo = String("+") + "901234567";
or
String a = "+"; String cepNo = a + "901234567";

Or, simply don't use the + operator.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Better way for connecting to Arduino pins to a sensor than jumper cable
Well I have an dht21 and arduino mega. Dht21 leads look like this

If I use jumper cable and soldering dht21 leads with jumper cable than plug-in my arduino's socket. it looks like this below image. It dont looks safe. If the device falls to the ground or something, the cables may come out of place or the place may loosen over time. If I solder the cables under the arduino, it will be hard and looks like ugly. What is the best solution to plug-in a sensor to arduino board.

There is also the option of a Prototyping Screw Shield which converts the Arduino pins into terminal screw blocks. This makes a more permanent connection without being completely permanent.

Remember the Arduino is a prototyping system and it should be easy to plug, unplug and move around connectors.
If you want a permanent solution, you should make your own PCB and you will have a huge choice of connectors suited for all imaginable purposes (for example the JST family of connectors).
There are some connectivity systems like the Grove connector that have attempted to standardize connectivity on Arduino and related platforms.

One option you have is to solder your sensor leads to a set of header pins. The friction of multiple pins secured in a header will be greater than that of individual jumpers. When soldering to the header pins, use a method to secure the pins from movement, as the heat of the soldering iron may soften the plastic holding the pins.
The image below, from Digikey, is representative and does not imply correct spacing or fit for an Arduino.

Arduino solder shields are also available. This is a complete circuit board, akin to StarCat's recommendation of a custom PCB, but off-the-shelf. It allows access to all pins on the specific Arduino for which it was designed. I consider this option excessive for three connections, but include it for completeness.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Why Arduino IDE is brignging wrong board name for ESP32 S3

I am designing a pcb for ESP32 S3 wroom-1 for testing pins which are safe to use.
My PCB look like this:

I program ESP32 S3 via USB interface gpio19 "D-" gpio20 "D+". When I plug in my usb, Arduino ide brings wrong name for my Esp32 board. By the way I use USB TYPE C. Everyday it gives different names. Correct one is "ESP32S3 DEV MODULE".
How can I set it to select the correct module automatically on Arduino Ide as ESP32S3 Dev Module?
WRONG 1

WRONG 2

WRONG 3

same board different names. interesting

I've noticed that some ESP32 boards have a USB-to-Serial chip that is programmed with a confusing (i.e. wrong) identifier. There's no way to change this, but it will not have any effect on the board's functionality as long as you select the right board when you're programming it.

After an Arduino IDE update 2.2, something was solved, yesterday (30,08,2023).
There is a new edit button appearing on the board selection menu and then Arduino ide recognises esp32 even after plugging out and in again.

You can just force Arduino IDE to recognise your board by locating your Boards Configuration File, putting in your VID and PID values, repackage and host the configurations and Point the Arduino IDE to your custom board manager URL.
On my MacBook device I have used ioreg -p IOUSB -l after plugging in a device and copy the idVendor, idProduct properties. These are the VID and PID values. On Windows you may open Device Manager, look under the Ports (COM & LPT), right click on your board (it might appear as a COM port) and choose "properties", go to "details" menu, and there from the dropdown menu, select "Hardware Ids". you should see values like VID_XXXX&PID_YYYY. these are your VID and PID. on Linux you may just use "lsusb" and find the vendor ID and PID there.
After finding those you must go to ESP32 board package directory and find boards.txt (https://github.com/espressif/arduino-esp32/blob/master/boards.txt). Find the line that starts with esp32s3.name=ESP32S3 Dev Module. There you must modify the PID and VID values with your actual VID and PID values that you collected as mentioned above. Replace 0xXXXX with your VID and 0xYYYY with your PID.
After modifying, you'll need to compress the entire board package directory into a ZIP archive. Make sure the directory structure remains intact so that the Arduino IDE can recognize and install it correctly.
Then you can create a new repository on GitHub, upload the ZIP archive to this repository, then click on the ZIP file inside the repository, then click the "Download" button. Copy the link.
Now you must go to the Arduino IDE, go to file -> preferences. in the "Additional Boards Manager URLs" field, click on the icon on the right to open a window where you can insert new lines. Add the direct link to your ZIP file and click OK. Go to Tools -> Board -> Boards Manager. then search for ESP32. your custom package should appear in the list. Click "Install". after it installs you are good to go.
VERY IMPORTANT EDIT: after investigating this issue a little more I have came to realisation that so called "random board names" that show up all have the same VID and PID values. The problem was not the incorrect VID and PID values for your board, the problem was that a bunch of other boards also have the same VID and PID values. A simple yet effective fix would be to assign random names to all the other ones than the one you want to use. Just edit the
adafruit_qtpy_esp32c3.vid.0=0x303a

adafruit_qtpy_esp32c3.pid.0=0x1001

lines for every board other than what you want to use. But never forget to change this text file if you ever start doing long-run development with one of the other boards. Or the other boards (such as u-blox NORA-W10 s3" won't be auto detected.

A comprehensive explanation of this also appears here: https://forum.arduino.cc/t/arduino-nano-esp32-board-is-always-identified-as-adafruit-esp32/1241431/2


text:
P10 LED Display Character Overlaying with DMD library

Hi, I am using p10 Led display and trying to make digital clock. it works fine but after 2 or more weeks later without any switch off there is a overlaying start on characters. why this happening I didnt understand. I am using classical DMD library but result here:

The same number appears very faintly above the number but slightly above and below. I am using ESP32 S3 also powering directly on USB 5V to panel VCC. and my adaptor is 25W for Samsung cellphone adaptor fast charge. even I call clearScreen command in every 30 minute but not works.

dmd.clearScreen( true );   //true is normal (all pixels off), false is
negative (all pixels on)

Why this happening and how to solve? Thanks.

I'd consider using a different library. Looking at the DMD GIT repository, there are unanswered questions that are over a year old. This one sounds similar to yours.

change your code so that the second line is not there ... that will show the extent of the corruption a bit better

please add a link to the display datasheet to your question ... also add the code that you are using

It sounds like a memory buffer gets corrupted resulting unexpected artifacts appearing on the display. As these types of displays are normally completely refreshed each frame, the corrupted memory likely in is the processor.
Consider adding:
   dmd.clearScreen(true);

... in the update loop before completely describing what is to be displayed. This line of code was found on line 84 of this DMD example code on the DMD GITLAB repository.

Added later...
Other possible causes to consider:

Some Arduino boards have linear power regulators which require higher voltages then that required to operate the processor. If you are using such an Arduino, make sure you allow for this unexpected consumption of voltage.
HUB 75 like displays need to be continuously updated and require consistent timing. Even though it may make this project pointless, consider removing any conditionally executed code which may disturb the timing of the HUB 75 like control signals.  Test the resulting code for any unexpected display behavior over similar time and under similar power conditions.
If powering the HUB 75 like display separately, make sure there is a robust common ground wire connecting the Arduino and HUB 75 like display.
Keep all wiring / cables as short as possible. In many examples, the HUB 75 like display cable is less than one foot (~30 cm) long.

Tomorrow i will try but i dont think it will be solution. İ dont think buffer can broken after weeks later. Beacuse unwanted leds are seen very faintly. İf buffer was broken overlaying characters should be bright as normal characters

Consider addressing the comments under your question. Also, consider some power supplies can be complex. A USB C power supply can operate at different voltages and my not reach it's claimed power capacity when used with a device that does not communicate with the power supply. Finally, some power supplies are cheaply made. Consider testing with a different power source.

well I have tested and result is almost same. flicker affect is still there @st2000

Sorry for asking, which test might have you done? 1) Clearing the buffer for every display refresh? 2) Changing the power supply for one with higher amp capacity?

I should add, some Arduinos have linear power regulators which require higher voltages then that required to operate the processor. And, HUB 75 like displays need to be continuously updated and require consistent timing.Perhaps conditionally executed code is causing timing issues. I'll add these points to my answer.


text:
Correct connections: 7-segment, 4-digit display with common anode
I see this connections for 4-digit display.

All used pins set up on output. But, really, is it correct connections?
Why it used A* input pins, and, digital pins set up on output, it is right?
Maybe all pins need used by digital pins with NPN transistors? Collector is 5V, Base - Arduino digital pin, emitter - resistor with display anode, next, collector is display segment pin,  Base - Arduino digital pin, emitter - Ground.
What resistance is needed for the resistor? I think, more than 220 Ohm?
Sorry, but I'm really a beginner in electronics.

Where is the datasheet for the display?

http://imgur.com/a/SIB0s

Where is the rest of the datasheet for the display?

(5-1.8)/220=0.014amps is within the UNO's allowed consumption, so you're fine there. that said, i would invest in a max7219 to free up all those pins and make coding simpler with existing libraries.

That circuit looks OK to me.  It will allow you to light (reliably) a single segment at a time.  The A* pins will be used in digital output mode.
The A* pins are connected to the four anodes of the digits - each digit has common anodes for all the segments.  They should be driven HIGH to 'select' a digit.
The D* pints are connected to the cathodes of each segment.  They should be driven LOW to light that segment.
For example, to light the 'A' segment of the first digit, you would set:

A1 HIGH, to drive the anode of the first segment
A2, A3, A3 LOW, so that the other three segments are not driven
D5 LOW, so that current flows from A1 to D5, lighting the digit
D6-D12 HIGH so that no current flows from A1 through any of the other segments.

The expectation is that you will cycle around (very fast), lighting each required segment on each required digit in turn.
Without a (proper) data sheet we can't tell you what the correct resistor value is, but the 220R shown is probably OK.

Thank you. I was looking for a datasheet on the marking, but I can not find the full description.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
How to use virtual connection between matlab simulik and arduino in isis proteus?
I don't know how to connect between matlab simulik and arduino card in isis proteus by using a virtual ports

have you looked at any of the tutorials on the internet?

Yes, but i didn't find answer to this question by tutorial

were you able to create a virtual port in proteus?

I don't know how to create it

then, you are asking the wrong question and you are searching for the wrong tutorial on the web ............ find a tutorial about creating a virtual port in proteus  ..... find one about creating a virtual port in matlab also ...... i think that you only have to do one for your purpose


text:
Low Power Library 4 seconds ON, 10 minutes OFF
Could someone please demonstrate how to use a counter with the Arduino 'low power' library to wait for 10 minutes then digitalWrite 4000, HIGH and loop. (I don't mean the simple 'blink' sketch).
I'm trying to save as much power as possible, so any advice is appreciated.
Thanks!

For low power you really need a better board (or own design). The Uno burns a lot of power on extra circuitry and LEDs. Low power library (mode) will not give much. The board will still draw approx. 10 mA.

And using counter means you can't go deeper than to the IDLE mode and it's not so "saving" at all. You can't use Timer2 in asynchronous mode on UNO, as there is crystal resonator for the main oscillator on the same pins.

In principle, you put the arduino in sleep mode (powerdown) and configure the watchdog timer to wake it up after a certain length of time. Since the maximum time is about 8 seconds, you have to cycle through about 80 wakeup cycle to achieve your 10 minutes.
Here is a good guide: https://www.gammon.com.au/forum/?id=11497

Your problem here is your 10 minutes mark. If you're willing to take a somewhat more complex route, you could use a low-power, programmable, external timer like TPL5110. You can set an interval of up to 120 minutes by selecting the appropriate value of the programming resistor.
This kind of timers can be used to drive the gate of a logic-level P-channel MOSFET that acts as a switch for the power line of the Arduino.

Then, you simply you do all your stuff on the setup() function and leave loop() empty. You can switch off the Arduino by sending back a DONE signal to the TPL5110 at the end for your setup().

If, for whatever reasons, you really want your Arduino to be running for exactly 3 seconds, then you should run a timer in it (beware: not related in any way with TPL5110). Set it up so you the ISR of the timer breaks a do-while waiting loop just before the line of code that sends back the DONE signal.

Agreed with what most others have already mentioned;
The Arduino as-is is not suitable for low power operation - it is best to turn it off completely. The circuit below should do what you want, and is based on a very simple and cheap IC, the 555 timer.

simulate this circuit – Schematic created using CircuitLab
A similar version of this has been working for me for about 2 years in a remote sensing setup. A few things to note to make sure that it works;

This needs the TLC555 chip which is a CMOS IC. The TTL version (NE555) will not work with such high value timing resistors.
The timing capacitor (shown as 141uF, just use 3 x 47uF in parallel) needs to be a tantalum capacitor. The normal electrolytic version has too high a leakage current.
As shown, this should turn off the Arduino for about 580s, and on for 120s. To turn off the Arduino sooner, drive digital pin 5 high. This will discharge C1 through R3 and Q1 quickly (about 500ms).
To change the delay times, alter R1, R2, and C1. The datasheet has all the equations that you need for this.
it would probably be wise to put a bypass capacitor between the supply rails very close to the TLC555 chip. 10uF should do.
This circuit should draw around 360uA while the Arduino is off.

One final thing - the task that you are using the Arduino for sounds pretty simple - driving a digital line high for 4 seconds every 10 minutes. I guess that you have more to it than that, but if not, then you could save yourself the cost and complexity, and do away with the Arduino completely. In that case, R1 should be about 6M1, and R2 about 41K, you can remove Q1, D1, R3 and R6, and whatever you are driving goes in place of the Arduino.

authors: พัฒนพงษ์ จันทะมาตย์

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
What difference between readString and while loop read
From Arduino code, I have a question for SoftwareSerial Class
First: when I use more example for Esp8266 those functions use while loop to read response string from Esp when we send AT_Command to ESP.
getResponse(const uint32_t  wait) {
    String tmpData = "";
    long int time = millis();
    while ((time + wait) > millis()) {
        while (esp8266->available() > 0) {
            char c = esp8266->read();
            if (c == '\0') continue;
            tmpData += c;
        }
    }
    tmpData.trim();
    return tmpData;
}

I know that SoftwareSerial Class have a public method is readString() then I'm tried to use that and it return same result returned by while loop read:
getResponse(const uint32_t  wait) {
    String tmpData = "";
    tmpData = esp8266->readString();
    return tmpData;
}

Thanks for any. I'm working on improving my Eng.
Regards

Your while loop reads all the characters up until it reaches character 0 (it also has a timeout, although the timeout has been coded wrong since it can't deal with clock rollover). The .readString() method reads characters until no characters arrive within a timeout period (1s if memory serves me correctly).
Your while loop is the more reliable method since it uses a specific delimiter to identify blocks of data (strings) rather than assuming that:

The string will all arrive with no delays greater than the timeout
The strings will be sent with a gap of at least the timeout length between them.

Personally I would never recommend using any of the "helpful" functions provided for reading from a Stream object other than the basic .read() function.


text:
Sending colours to vga monitor
I'm looking for a simple way to send a signal from my arduino to a vga monitor.
What would be the easiest method, and what components would be needed?
I don't need to display an image, just a solid colour.

See if this helps.

My page about Arduino Uno output to VGA monitor has a lot of theory on it, including a sketch that produces colour bars like this:

Code
To produce a single colour is slightly simpler, this sketch did it for me:
/*
 VGA colour video generation

 Author:   Nick Gammon
 Date:     22nd April 2012
 Version:  1.0

 Connections:

 D3 : Horizontal Sync (68 ohms in series) --> Pin 13 on DB15 socket
 D4 : Red pixel output (470 ohms in series) --> Pin 1 on DB15 socket
 D5 : Green pixel output (470 ohms in series) --> Pin 2 on DB15 socket
 D6 : Blue pixel output (470 ohms in series) --> Pin 3 on DB15 socket
 D10 : Vertical Sync (68 ohms in series) --> Pin 14 on DB15 socket

 Gnd : --> Pins 5, 6, 7, 8, 10 on DB15 socket

*/

#include <TimerHelpers.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>

const byte hSyncPin = 3;     // <------- HSYNC

const byte redPin = 4;       // <------- Red pixel data
const byte greenPin = 5;     // <------- Green pixel data
const byte bluePin = 6;      // <------- Blue pixel data

const byte vSyncPin = 10;    // <------- VSYNC

const int horizontalBytes = 60;  // 480 pixels wide
const int verticalPixels = 480;  // 480 pixels high

// Timer 1 - Vertical sync

// output    OC1B   pin 16  (D10) <------- VSYNC

//   Period: 16.64 ms (60 Hz)
//      1/60 * 1e6 = 16666.66 µs
//   Pulse for 64 µs  (2 x HSync width of 32 µs)
//    Sync pulse: 2 lines
//    Back porch: 33 lines
//    Active video: 480 lines
//    Front porch: 10 lines
//       Total: 525 lines

// Timer 2 - Horizontal sync

// output    OC2B   pin 5  (D3)   <------- HSYNC

//   Period: 32 µs (31.25 kHz)
//      (1/60) / 525 * 1e6 = 31.74 µs
//   Pulse for 4 µs (96 times 39.68 ns)
//    Sync pulse: 96 pixels
//    Back porch: 48 pixels
//    Active video: 640 pixels
//    Front porch: 16 pixels
//       Total: 800 pixels

// Pixel time =  ((1/60) / 525 * 1e9) / 800 = 39.68  ns
//  frequency =  1 / (((1/60) / 525 * 1e6) / 800) = 25.2 MHz

// However in practice, it we can only pump out pixels at 375 ns each because it
//  takes 6 clock cycles to read one in from RAM and send it out the port.

const byte verticalBackPorchLines = 35;  // includes sync pulse?
const int verticalFrontPorchLines = 525 - verticalBackPorchLines;

volatile int vLine;
volatile byte backPorchLinesToGo;

#define nop asm volatile ("nop\n\t")

// ISR: Vsync pulse
ISR (TIMER1_OVF_vect)
  {
  vLine = 0;
  backPorchLinesToGo = verticalBackPorchLines;
  } // end of TIMER1_OVF_vect

// ISR: Hsync pulse ... this interrupt merely wakes us up
EMPTY_INTERRUPT  (TIMER2_OVF_vect)

void setup()
  {

  // disable Timer 0
  TIMSK0 = 0;  // no interrupts on Timer 0
  OCR0A = 0;   // and turn it off
  OCR0B = 0;

  // Timer 1 - vertical sync pulses
  pinMode (vSyncPin, OUTPUT);
  Timer1::setMode (15, Timer1::PRESCALE_1024, Timer1::CLEAR_B_ON_COMPARE);
  OCR1A = 259;  // 16666 / 64 µs = 260 (less one)
  OCR1B = 0;    // 64 / 64 µs = 1 (less one)
  TIFR1 = bit (TOV1);   // clear overflow flag
  TIMSK1 = bit (TOIE1);  // interrupt on overflow on timer 1

  // Timer 2 - horizontal sync pulses
  pinMode (hSyncPin, OUTPUT);
  Timer2::setMode (7, Timer2::PRESCALE_8, Timer2::CLEAR_B_ON_COMPARE);
  OCR2A = 63;   // 32 / 0.5 µs = 64 (less one)
  OCR2B = 7;    // 4 / 0.5 µs = 8 (less one)
  TIFR2 = bit (TOV2);   // clear overflow flag
  TIMSK2 = bit (TOIE2);  // interrupt on overflow on timer 2

  // prepare to sleep between horizontal sync pulses
  set_sleep_mode (SLEEP_MODE_IDLE);

  // pins for outputting the colour information
  pinMode (redPin, OUTPUT);
  pinMode (greenPin, OUTPUT);
  pinMode (bluePin, OUTPUT);

}  // end of setup

// draw a single scan line
void doOneScanLine ()
  {

  // after vsync we do the back porch
  if (backPorchLinesToGo)
    {
    backPorchLinesToGo--;
    return;
    }  // end still doing back porch

  // if all lines done, do the front porch
  if (vLine >= verticalPixels)
    return;

  PORTD = bit (5) | bit (6);  // cyan (green + blue)
  delayMicroseconds (27);     // one scan line

  PORTD = 0;  // back to black
  // finished this line
  vLine++;

  }  // end of doOneScanLine

void loop()
  {
  // sleep to ensure we start up in a predictable way
  sleep_mode ();
  doOneScanLine ();
 }  // end of loop

As @ChrisStratton suggested, the hardware timers are a big help.

Wiring
I wired it up like this:

TimerHelpers library
The TimerHelpers.h library is described on my timers page, a copy is below:
/*
 Timer Helpers library.

Devised and written by Nick Gammon.
Date: 21 March 2012
Version: 1.0

Licence: Released for public use.

See: http://www.gammon.com.au/forum/?id=11504

 Example:

 // set up Timer 1
 TCNT1 = 0;         // reset counter
 OCR1A =  999;       // compare A register value (1000 * clock speed)

 // Mode 4: CTC, top = OCR1A
 Timer1::setMode (4, Timer1::PRESCALE_1, Timer1::CLEAR_A_ON_COMPARE);

 TIFR1 |= bit (OCF1A);    // clear interrupt flag
 TIMSK1 = bit (OCIE1A);   // interrupt on Compare A Match

*/

#ifndef _TimerHelpers_h
#define _TimerHelpers_h

#include <Arduino.h>

/* ---------------------------------------------------------------
 Timer 0 setup
 --------------------------------------------------------------- */

namespace Timer0
{
  // TCCR0A, TCCR0B
  const byte Modes [8] [2] =
  {

  { 0,                         0 },            // 0: Normal, top = 0xFF
  { bit (WGM00),               0 },            // 1: PWM, Phase-correct, top = 0xFF
  {               bit (WGM01), 0 },            // 2: CTC, top = OCR0A
  { bit (WGM00) | bit (WGM01), 0 },            // 3: Fast PWM, top = 0xFF
  { 0,                         bit (WGM02) },  // 4: Reserved
  { bit (WGM00),               bit (WGM02) },  // 5: PWM, Phase-correct, top = OCR0A
  {               bit (WGM01), bit (WGM02) },  // 6: Reserved
  { bit (WGM00) | bit (WGM01), bit (WGM02) },  // 7: Fast PWM, top = OCR0A

  };  // end of Timer0::Modes

  // Activation
  // Note: T0 is pin 6, Arduino port: D4
  enum { NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_64, PRESCALE_256, PRESCALE_1024, T0_FALLING, T0_RISING };

  // what ports to toggle on timer fire
  enum { NO_PORT = 0,

    // pin 12, Arduino port: D6
    TOGGLE_A_ON_COMPARE  = bit (COM0A0),
    CLEAR_A_ON_COMPARE   = bit (COM0A1),
    SET_A_ON_COMPARE     = bit (COM0A0) | bit (COM0A1),

    // pin 11, Arduino port: D5
    TOGGLE_B_ON_COMPARE  = bit (COM0B0),
    CLEAR_B_ON_COMPARE   = bit (COM0B1),
    SET_B_ON_COMPARE     = bit (COM0B0) | bit (COM0B1),
  };

  // choose a timer mode, set which clock speed, and which port to toggle
  void setMode (const byte mode, const byte clock, const byte port)
  {
  if (mode < 0 || mode > 7)  // sanity check
    return;

  // reset existing flags
  TCCR0A = 0;
  TCCR0B = 0;

  TCCR0A |= (Modes [mode] [0]) | port;
  TCCR0B |= (Modes [mode] [1]) | clock;
  }  // end of Timer0::setMode

}  // end of namespace Timer0

/* ---------------------------------------------------------------
 Timer 1 setup
 --------------------------------------------------------------- */

namespace Timer1
{
  // TCCR1A, TCCR1B
  const byte Modes [16] [2] =
  {

  { 0,                         0 },            // 0: Normal, top = 0xFFFF
  { bit (WGM10),               0 },            // 1: PWM, Phase-correct, 8 bit, top = 0xFF
  {               bit (WGM11), 0 },            // 2: PWM, Phase-correct, 9 bit, top = 0x1FF
  { bit (WGM10) | bit (WGM11), 0 },            // 3: PWM, Phase-correct, 10 bit, top = 0x3FF
  { 0,                         bit (WGM12) },  // 4: CTC, top = OCR1A
  { bit (WGM10),               bit (WGM12) },  // 5: Fast PWM, 8 bit, top = 0xFF
  {               bit (WGM11), bit (WGM12) },  // 6: Fast PWM, 9 bit, top = 0x1FF
  { bit (WGM10) | bit (WGM11), bit (WGM12) },  // 7: Fast PWM, 10 bit, top = 0x3FF
  { 0,                                       bit (WGM13) },  // 8: PWM, phase and frequency correct, top = ICR1
  { bit (WGM10),                             bit (WGM13) },  // 9: PWM, phase and frequency correct, top = OCR1A
  {               bit (WGM11),               bit (WGM13) },  // 10: PWM, phase correct, top = ICR1A
  { bit (WGM10) | bit (WGM11),               bit (WGM13) },  // 11: PWM, phase correct, top = OCR1A
  { 0,                         bit (WGM12) | bit (WGM13) },  // 12: CTC, top = ICR1
  { bit (WGM10),               bit (WGM12) | bit (WGM13) },  // 13: reserved
  {               bit (WGM11), bit (WGM12) | bit (WGM13) },  // 14: Fast PWM, TOP = ICR1
  { bit (WGM10) | bit (WGM11), bit (WGM12) | bit (WGM13) },  // 15: Fast PWM, TOP = OCR1A

  };  // end of Timer1::Modes

  // Activation
  // Note: T1 is pin 11, Arduino port: D5
  enum { NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_64, PRESCALE_256, PRESCALE_1024, T1_FALLING, T1_RISING };

  // what ports to toggle on timer fire
  enum { NO_PORT = 0,

    // pin 15, Arduino port: D9
    TOGGLE_A_ON_COMPARE  = bit (COM1A0),
    CLEAR_A_ON_COMPARE   = bit (COM1A1),
    SET_A_ON_COMPARE     = bit (COM1A0) | bit (COM1A1),

    // pin 16, Arduino port: D10
    TOGGLE_B_ON_COMPARE  = bit (COM1B0),
    CLEAR_B_ON_COMPARE   = bit (COM1B1),
    SET_B_ON_COMPARE     = bit (COM1B0) | bit (COM1B1),
  };

  // choose a timer mode, set which clock speed, and which port to toggle
  void setMode (const byte mode, const byte clock, const byte port)
  {
  if (mode < 0 || mode > 15)  // sanity check
    return;

  // reset existing flags
  TCCR1A = 0;
  TCCR1B = 0;

  TCCR1A |= (Modes [mode] [0]) | port;
  TCCR1B |= (Modes [mode] [1]) | clock;
  }  // end of Timer1::setMode

}  // end of namespace Timer1

/* ---------------------------------------------------------------
 Timer 2 setup
 --------------------------------------------------------------- */

namespace Timer2
{
  // TCCR2A, TCCR2B
  const byte Modes [8] [2] =
  {

  { 0,                         0 },            // 0: Normal, top = 0xFF
  { bit (WGM20),               0 },            // 1: PWM, Phase-correct, top = 0xFF
  {               bit (WGM21), 0 },            // 2: CTC, top = OCR2A
  { bit (WGM20) | bit (WGM21), 0 },            // 3: Fast PWM, top = 0xFF
  { 0,                         bit (WGM22) },  // 4: Reserved
  { bit (WGM20),               bit (WGM22) },  // 5: PWM, Phase-correct, top = OCR2A
  {               bit (WGM21), bit (WGM22) },  // 6: Reserved
  { bit (WGM20) | bit (WGM21), bit (WGM22) },  // 7: Fast PWM, top = OCR2A

  };  // end of Timer2::Modes

  // Activation
  enum { NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_32, PRESCALE_64, PRESCALE_128, PRESCALE_256, PRESCALE_1024 };

  // what ports to toggle on timer fire
  enum { NO_PORT = 0,

    // pin 17, Arduino port: D11
    TOGGLE_A_ON_COMPARE  = bit (COM2A0),
    CLEAR_A_ON_COMPARE   = bit (COM2A1),
    SET_A_ON_COMPARE     = bit (COM2A0) | bit (COM2A1),

    // pin 5, Arduino port: D3
    TOGGLE_B_ON_COMPARE  = bit (COM2B0),
    CLEAR_B_ON_COMPARE   = bit (COM2B1),
    SET_B_ON_COMPARE     = bit (COM2B0) | bit (COM2B1),
  };

  // choose a timer mode, set which clock speed, and which port to toggle
  void setMode (const byte mode, const byte clock, const byte port)
  {
  if (mode < 0 || mode > 7)  // sanity check
    return;

  // reset existing flags
  TCCR2A = 0;
  TCCR2B = 0;
  TimerHelpers.h
  TCCR2A |= (Modes [mode] [0]) | port;
  TCCR2B |= (Modes [mode] [1]) | clock;
  }  // end of Timer2::setMode

}  // end of namespace Timer2

#endif

References

Timers
Interrupts
Arduino Uno output to VGA monitor

Just one quick follow on question. What do I have to search to obtain a connection for a vga cable?

@Terry "VGA female connector" (female connector means you plug a male connector in)

A quick Google search for "Arduino VGA" will give you a lot of information. There are a few variations on both circuits and programming, which also vary in resolution and color depth.
I was searching for this a few days ago, and these are my favorite (so far):

http://labdegaragem.com/profiles/blogs/gerando-sinal-vga-colorido-com-arduino-completo (it is in portuguese, but you can get a pretty good idea of what to do)
https://forum.arduino.cc/index.php?topic=320238.0 (read the whole discussion, pretty nice results)

If using a TV is also a plausible option, check the Arduino TV out library. It can be installed directly from the Arduino IDE and has a good demo.

Not needing to display an actual image simplifies things substantially, as an Arduino lacks the memory and (except in a crude sense) the bandwidth to do so.
However, you cannot simply apply a steady analog voltage to the R, G, and B lines.  Not only do you have to drive horizontal and vertical sync signals, you have to blank the RGB signals when not on the active portion of the screen, otherwise the monitor will assume their steady voltage means "black" and your colors will last only as a brief flash when your device is first connected or enabled.
Generating a large rectangular field of color from an Arduino is likely to be rather challenging, but probably not impossible.  You may be able to use hardware PWM channels for the horizontal and a "color enable", and tightly coded software counters for the vertical aspect.  You can then use the "color enable" to gate a network of potentially variable resistors to establish the single color of particular interest.


text:
Are there sensors that can detect the color of an LED?
Are there sensors that can detect the color of an LED?
I am working on an Arduino project that needs to detect the color of an LED on an external device. I am trying to identify a light sensor that can be connected to the Arduino's input that can tell me the color of light the LED is currently emitting. The LED is capable of displaying red, green and yellow.

Take a look at AMS color sensors family for example. One of them in a Adafruit: https://www.adafruit.com/products/1334

E.g. http://www.ebay.com/itm/TCS230-TCS3200-Color-Recognition-Sensor-Detector-Module-For-MCU-Arduino-M7-/351493999961?hash=item51d6accd59:g:wMIAAOSwPcVVwHPf

You mean like this one?
Adafruit RGB Color Sensor
They have similar products in different form factors.

There are a few different things you can do to detect a color.
The Arduino starter kit that I got when I first got into Arduino had some photoresistors plus some colored films. One of the projects in the project book had you put a different color film over each photoresistor, so that only that color of light would hit the sensor. You could do something like that if you only need to check for a small number of distinct colors.
There are also a wide array of color sensors and sensor modules available (just search your favorite online store for "color sensor" or "arduino color sensor"), which will allow for far more detailed and precise color readings, but at a higher price point.

You can use an LED as a light sensor - http://www.instructables.com/id/LEDs-as-light-sensors/
In theory, LEDs should be most sensitive to the frequency it emits - if this is true, the same type of red/green/yellow LED would be best.
I don't know how sensitive this will be.
If you control the "external device", then you could get much better accuracy by blinking the LED at very high rates (not visible to the human eye). Or, if you can get at the legs of the LED, you can tap into the signal directly (you should use an opto-isolator - even if powered at a few volts, the ground of your project may be different from the ground of the external device, causing 100s of volts to run through your Arduino - not good!).


text:
Is it possible to control a 12v led matrix with an arduino?
This is a bit home automation but if I want to control my 12v LEDs and I have 8 free pins would it be possible to drive 16 lights as a matrix. I was looking into running 8 LEDs with an 8 channel relay but the I got to thinking if I wire up 16 LEDs in a matrix I could still control them all with those 8 channels. Problem is I was looking at mechanical relays that would burn out very quickly with that kind of switching. Are there any other solutions?

Why mechanical relays? since they are 12V leds you will need 12 MOS (4 nMOS on the columns, 4 pMOS on the rows and 4 more nMOS to pull the pMOS gate to ground (since your arduino can output at most 5V). they are much cheaper than relays, much smaller, much faster and will last much longer...

I originally found the relays that we rated for ac and DC and it seemed nice to have the option.I started looking into solid state relays but couldn't find a balance between price, quality, and available datasheets. I'm way more of a software guy so that explains why transistors slipped my mind

If you want AC support then you'll definitely need to wire them one by one, or you'll maybe get some weird behavior. As for relays, you will not be able to use them in a matrix. The reason, apart from the wearing, is that a common relay needs 10-20ms to switch, and you will need at least 200 flashes per second (but more is much better) to get an acceptable light. I mean, if you turn on an led for 10ms and then off for 30ms (100Hz switching frequency) your light will blink at 25Hz, and your eye will see the light "flashing", which is really tiring for the eyes. So.. Just go with transistors ;)

@frarugi87 Yes, thanks again, I decided 120vac would be many more problems than it's worth and I have a main priority of not burning the house down :)

@JacobKern How's your project going? Did the answer lead to a solution?

You can use ULN2803 driver IC on sink side (cathode), P channel MOSFET on anode/source side of common anode LED matrix. Since you need only 4 sinks you can pair every 2 i/o of ULN2803 so you can drive/sink 1A max load per row. This IC is cheap and widely available.
MOSFET current and speed should match those of ULN2803. You can use BJT instead of MOSFET, but voltage drop on BJT will be higher.
Similar design is here: 8x8 LED matrix

The real gem is your similar design. It shows two daisy-chained shift registers. So with the 4 pins, you can drive the two shift registers, who drive the P-channel and ULN2803. Effectively 8x8 with only 4 inputs and it's even very scaleable.

I think the best solution would be to use WS2812 LEDS. I already implemented this many times also for my home illumination.
WS2812 is a RGB LED with an integrated chip (1m strip with 60 LED will cost about 10$).
One advantage is that you need only 1 output from your Arduino and the library works very well.
Another one is that you don't need power! 5mA is enough to drive 1000 LEDS! So you don't need MOSFETS and you don't need any Relais.

I would choose an SPI based digital ledstrip. They're easier to control with various devices and leave soms time inbetween setting pixels to be able to calculatie the next one. Which is much more memory efficiënt.


text:
External 5V Power and USB Serial
I have a Chinese Arduino nano clone, but I don't know if it's possible to connect the Arduino to external (5v) power and have a USB serial connection ongoing. I'm trying to make a PC controlled LED Strip that can also work on its own.
For example: the PC controls the Arduino sets it to a specific mode and I turn off the PC, but the Arduino should still be running even when the PC is turned off.
I'm new to the world of arduinos.
I'm planning to use this to control addressable LED RGB Strips and am planning to use a 4000mA max power supply.

Why don't you try to connect it and see for yourself?

i am afraid that i will fry my pc or arduino

Then you might want to buy genuine parts, or at least parts with a schematic you could analyse for such risks.

@DmitryGrigoryev  "Arduino" is an open source hardware and software system. Ones made by other than holders of the now several trademartks are just as genuine as "originals" if they implement  the core features. Use of the term "genuine parts" in this manner is against the spririt which the whole concept of "open source" seeks to promote.

Having used counterless Arduinos and clones, I can tell you that you can connect both without worrying about any danger. Unless you have a very faulty board, your pc won't be damaged, almost surely neither will the board, as is should select the most powerful source, between your usb or a battery/external PS, while leaving untouched the serial line.

this is the answer i needed thank you very much, but just to be sure have you ever fried something that way?

@TheKayneGame never

If you have solved your problem, please choose one of the answers; so that anyone with a similar problem can read it too

If you are new to something, you should start with reading manual.
Here's what official Wiki page of arduino nano says:
https://www.arduino.cc/en/Main/ArduinoBoardNano

Power:
The Arduino Nano can be powered via the Mini-B USB connection, 6-20V unregulated external power supply (pin 30), or 5V regulated external power supply (pin 27). The power source is automatically selected to the highest voltage source.

So to be sure i won't fry my arduino or my pc when connecting 5v to pin 27 and connect the arduino to my pc at the same time?

For a genuine Arduino Nano you would be fine. For a cheap clone who knows, it depends if they skipped some parts to save money.

Make sure you external power is regulated and connected to the same AC source as you pc. Should be perfectly fine then.
Also refer to this thread for additional points regarding safety:
http://arduino.stackexchange.com/questions/11885/is-supplying-5v-from-both-external-5v-and-usb-harmful?rq=1

The info about 100/150mA USB capability in PC is incorrect. Any normal (not "low-power embedded") USB host must supply 500mA (for USB2.0 ports) and 900mA for USB3.0 ports. In a typical PC this power comes from standby +5VSB rail from system Power Supply. Power rating for this rail is no less than 2A for AT12 compliant PC. Of course it is not advisable to take all this power from one port, due to contact rating limits, and possible polyswitch overcurrent protection of USB ports.
Therefore, if the attached USB device draws total less than 1-1.5A, the design should work fine even if PC is in standby mode (turned off but still connected to AC outlet).
However it is still preferable to use a stand-alone power for this kind of projects. The Arduino board must be designed in a way that, if connected to external higher-voltage source, it would not backdrive any significant current into USB VBUS pin. Usually it gets accomplished by means of one single Schottky diode between VBUS and internal power rail on Arduino board.
You can check if your Arduino drives anything back: power the Arduino with, say, 12V power supply, and check with a Multimeter if VBUS pin on the (unattached) USB connector has any voltage. You should load the VBUS with 10k-15k resistor, and the voltage should be small, 200mV or less, if I remember correctly.
ADDENDUM1: Just checked with Arduino-nano schematics. Yes, there is a "auto selecting" Schottky diode, so there will be no backvoltage on VBUS. However, the Arduino design violates another USB requirement - no signal on any connector pin when VBUS is inactive (low). In the Arduino-nano the VBUS does not control the state of FT232 bridge, so it will always pull-up D+ (USBDP) line as soon as 5V is applied, which is in violation of specs. The side effect of this back-driving is that your PC might not re-connect with the Arduino after waking-up, although it is a rare case these days.

You can connect the Arduino nano to recommended external power supply i.e 5V when it acts as a standalone device with other circuitry. As it is connected to PC it starts drawing power from PC(as PC is acting as a host here) and at the same time serial communication goes on. Now if you want to simultaneously connect the nano to PC or any other host say tablet and external power supply it is recommended that you go for an OTG cable cum power splitter y-cable.
But do not rely on power from PC if you have many sensors or components interfaced to aduino nano as PC is capable of giving max current 100mA in USB 2.0 and approx 150mA in USB 3.0

I was not planning to use PC power alone, and the current draw will be around 3 to 4 Ampère.

authors: женя прунькин


text:
Prevent 5V output on Arduino Nano 5V pin
I just made an addressable RGB LED strip controller but im concerned about if I'm going to break the thing.
I know it sounds vague so let me elaborate: there is an external power supply connected to my 5V pin and the LED strips positive so it powers both the strip and Arduino, but I also have my Arduino connected to my PC at all times. So I'm concerned about IF my power supply is for some reason not connected the Arduino will supply power on its own.
Is there a way to prevent 5V pin from outputting 5V, so it only accepts 5V
EDIT:
There are cases when the USB isn't connected so I need the 5V to be connected at all times, if its still vague then is there a way to only use data on USB and disregard the power?

If it's always connected to the PC why not just disconnect the 5V pin?

@Majenko the current drwa is around 4 amps and i forgot to mention that its only connected when pc is on

So you want it to operate when the PC is off?

@Majenko when its onn and off but when the pc is on the arduino will listen to the pc for commands

Sorry, you're not making any sense now.

A simple diode is all you need. The USB power already goes through a diode, so another diode the same will create a "highest voltage wins" situation.
That is, if the voltage provided by the USB port is higher than the voltage you provide on the +5V pin (after the diode's forward voltage drop) then the USB port will power the nano. If the voltage on the +5V pin is higher (after the diode's voltage drop) than the USB then the voltage on the +5V pin will power the nano.
No power will flow out of the 5V pin to your LED strip because the diode is in the way.
Connect the 5V external power to the anode of the diode, and the 5V pin of the Arduino to the cathode of the diode. The cathode is generally the end of the diode with the stripe.  Make sure the diode can pass enough current to power the Arduino when the USB is un-powered. The 1N4001 is a popular choice and very easy to get hold of.
That choice of diode also has a higher forward voltage drop than the on-board USB diode (0.7V as opposed to about 0.4V), so the USB will generally be chosen by default when connected and powered up, which is as it should be for a bus-powered device.


text:
Is it possible to run Python embedded in Arduino?
I know how to program in C but I'm more productive in python, so, I would like to know if there is a way to run a python code into arduino.

http://playground.arduino.cc/CommonTopics/PyMite

The whole concept just makes me break out in a cold sweat and rock quietly in the corner...

You can use other kind of board called MicroPython
But yes, is possible using some kind of TX-RX Python class...


text:
Why does Serial.write() work but Serial.print() doesn't?
I am testing my GPS module with an ESP32 using the Arduino IDE. I'm asking because I usually don't fully understand the difference between Serial.write() and Serial.print().
This code is working perfectly with Serial.write() and the output is meaningful:
void loop() {
  while (Serial2.available() > 0) {
    Serial.write(Serial2.read());
  }

  Serial.println("-------------------------------------");
}

Output:
13:28:05.173 -> -------------------------------------
13:28:05.206 -> $GPRMC,,V,,,,,,,,,,N*53
13:28:05.238 -> $GPVTG,,,,,,,,,N*30
13:28:05.238 -> $GPGGA,,,,,,0,00,99.99,,,,,,*48
13:28:05.270 -> $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
13:28:05.334 -> $GPGSV,1,1,00*79
13:28:05.334 -> $GPGLL,,,,,,V,N*64
13:28:05.366 -> -------------------------------------

When I convert this code to Serial.print() the output looks strange:
void loop() {
  while (Serial2.available() > 0) {
    Serial.print(String(Serial2.read()));
  }

  Serial.println("-------------------------------------");
}

Output:
13:26:43.118 -> -------------------------------------
13:26:43.150 -> -------------------------------------
13:26:43.214 -> 367180827767444486444444444444444444447842535113103671808684714444444444444444447842514813103671807171654444444444444844484844575746575744444444444442525613103671807183654465444944444444444444444444444444575746575744575746575744575746575742514813103671807183864449444944484842555713103671807176764444444444448644784254521310-------------------------------------
13:26:43.566 -> -------------------------------------
13:26:43.629 -> -------------------------------------

Why does Serial.write work, but Serial.print doesn't? Or: how to write the same code with Serial.print()?

Why does Serial.write work, but Serial.print doesn't?

Serial.read() returns an integer for each byte from the serial port.
String converts each integer to its decimal ASCII representation (e.g. $ = "36", G = "71" etc), so Serial.print() receives an ASCII string with the decimal values of each input byte, which were already ASCII. This is probably not what you want.

i only use this to get data from the GPS module, no need for library
you need to declare an array, say gps_rawData[200] = {0};
while (SerialGPS.available()) {
size_t byteCount = SerialGPS.readBytesUntil('\n', gps_rawData,
sizeof(gps_rawData) - 1);
gps_rawData[byteCount] = NULL;
String gps_rawDataString = String(gps_rawData);
SerialMon.println(gps_rawDataString);
}
this way you have the data in an array to be manipulated whenever or wherever required.

They're asking about why Serial.write behaves one way and Serial.print behaves a different way, which is answered by devnull.


text:
ESP32 Bluetooth Pair scanFilter not working properly
I am trying to make a bluetooth device with esp32 s3. Pairing should work like a headfone. At the First start, any device can connect my ble ESP32 after connecting I will add in whitelist this device which is connetted my esp32 new. even if this divice disconnect only this device can see my bluetooth network and only this device can connect this network. For this I saw this code setScanFilter(true, true); The logic of the code is exactly what I want, but it doesn't work as I imagined. After a phone connects to the network, it cannot reconnect to the same network. Moreover, a PC can see the network when no phone is connected, but it cannot connect either. However, what I want is this: once a phone connects to the network, whether it is currently connected or not, only that phone should be able to see and connect to the network.
this my test code:
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEAdvertising.h>

BLEServer* pServer = nullptr;
bool deviceConnected = false;
bool oldDeviceConnected = false;
BLEAddress whitelistDevice("00:00:00:00:00:00");

// BLEServerCallbacks sınıfı
class MyServerCallbacks : public BLEServerCallbacks {
  void onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t* param) override {

    whitelistDevice = BLEAddress(param->connect.remote_bda);
    Serial.print("Device added to whitelist: ");
    Serial.println(whitelistDevice.toString().c_str());
    delay(500);

    deviceConnected = true;
  }

  void onDisconnect(BLEServer* pServer) {
    deviceConnected = false;
  }
};

void setup() {
  Serial.begin(115200);
  // BLE cihazını başlat
  BLEDevice::init("truefalse");
  // Sunucuyu oluştur ve callback ayarla
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  // Reklam oluştur
  BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->setScanFilter(false, false);  // Whitelist'i etkinleştir
  pAdvertising->start();
  Serial.println("Advertising started without whitelist.");
}

void loop() {
  // Bağlantı kesildiğinde reklamları yeniden başlat
  if (!deviceConnected && oldDeviceConnected) {
    delay(500);  // BLE yığını için bekleme

    BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
    // Reklamları durdur
    pAdvertising->stop();
    Serial.println("Advertising stopped.");
    delay(500);
    // Beyaz liste filtresini etkinleştir
    BLEDevice::whiteListAdd(whitelistDevice);

    Serial.print("Device added to whitelist: ");
    Serial.println(whitelistDevice.toString().c_str());

    pAdvertising->setScanFilter(true, true);  // Beyaz liste filtresini etkinleştir
    // Reklamları yeniden başlat
    pAdvertising->start();
    Serial.println("Advertising restarted with whitelist filter.");

    Serial.println("Advertising restarted.");
    oldDeviceConnected = deviceConnected;
  }
  // Bağlantı kurulduğunda durum güncellemesi
  if (deviceConnected && !oldDeviceConnected) {
    oldDeviceConnected = deviceConnected;
    Serial.println("Device connected.");
  }
  delay(1000);
}


text:
Liquid level sensor
We're currently working on a direct sketch to printed circuit board printer for our design project. We need a sensor for the ink level since we're using a pen. Can we use this ( https://www.dfrobot.com/wiki/index.php/Non-contact_Liquid_Level_Sensor_XKC-Y25-T12V_SKU:_SEN0204) as a sensor even if its non-conductive type ink (normal ink we use for writing)? Thanks for the response!

Your link page says:

There are no special requirements for the liquid

So, I would not concern about the conductivity of the liquid.


text:
code optimazation 6x6 Matrix
I planed a 6x6 matrix with a Arduino Nano as controller.
Its only possible to let one LED in the matrix lighten up.
Any idea how I get the Code smaller? (Im a C Noobie ^^)
~Nico
Circuit diagram:

Code:

void setup() {
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(14, INPUT);
  pinMode(15, INPUT);
  pinMode(16, INPUT);
  pinMode(17, INPUT);
}

void loop() {
  int value1 = digitalRead(14);
  int value2 = digitalRead(15);
  int value3 = digitalRead(16);
  int test = digitalRead(17);
  int x1 = 2;
  int x2 = 3;
  int x3 = 4;
  int x4 = 5;
  int x5 = 6;
  int x6 = 7;
  int y1 = 8;
  int y2 = 9;
  int y3 = 10;
  int y4 = 11;
  int y5 = 12;
  int y6 = 13;

  // put your main code here, to run repeatedly:

  if (test == HIGH) {
    digitalWrite(x1, HIGH);
    digitalWrite(y1, HIGH);
    delay(15);
    digitalWrite(y1, LOW);
    digitalWrite(y2, HIGH);
    delay(15);
    digitalWrite(y2, LOW);
    digitalWrite(y3, HIGH);
    delay(15);
    digitalWrite(y3, LOW);
    digitalWrite(y4, HIGH);
    delay(15);
    digitalWrite(y4, LOW);
    digitalWrite(y5, HIGH);
    delay(15);
    digitalWrite(y5, LOW);
    digitalWrite(y6, HIGH);
    delay(15);
    digitalWrite(y6, LOW);
    digitalWrite(x1, LOW);
    digitalWrite(x2, HIGH);
    digitalWrite(y1, HIGH);
    delay(15);
    digitalWrite(y1, LOW);
    digitalWrite(y2, HIGH);
    delay(15);
    digitalWrite(y2, LOW);
    digitalWrite(y3, HIGH);
    delay(15);
    digitalWrite(y3, LOW);
    digitalWrite(y4, HIGH);
    delay(15);
    digitalWrite(y4, LOW);
    digitalWrite(y5, HIGH);
    delay(15);
    digitalWrite(y5, LOW);
    digitalWrite(y6, HIGH);
    delay(15);
    digitalWrite(y6, LOW);
    digitalWrite(x2, LOW);
    digitalWrite(x3, HIGH);
    digitalWrite(y1, HIGH);
    delay(15);
    digitalWrite(y1, LOW);
    digitalWrite(y2, HIGH);
    delay(15);
    digitalWrite(y2, LOW);
    digitalWrite(y3, HIGH);
    delay(15);
    digitalWrite(y3, LOW);
    digitalWrite(y4, HIGH);
    delay(15);
    digitalWrite(y4, LOW);
    digitalWrite(y5, HIGH);
    delay(15);
    digitalWrite(y5, LOW);
    digitalWrite(y6, HIGH);
    delay(15);
    digitalWrite(y6, LOW);
    digitalWrite(x3, LOW);
    digitalWrite(x4, HIGH);
    digitalWrite(y1, HIGH);
    delay(15);
    digitalWrite(y1, LOW);
    digitalWrite(y2, HIGH);
    delay(15);
    digitalWrite(y2, LOW);
    digitalWrite(y3, HIGH);
    delay(15);
    digitalWrite(y3, LOW);
    digitalWrite(y4, HIGH);
    delay(15);
    digitalWrite(y4, LOW);
    digitalWrite(y5, HIGH);
    delay(15);
    digitalWrite(y5, LOW);
    digitalWrite(y6, HIGH);
    delay(15);
    digitalWrite(y6, LOW);
    digitalWrite(x4, LOW);
    digitalWrite(x5, HIGH);
    digitalWrite(y1, HIGH);
    delay(15);
    digitalWrite(y1, LOW);
    digitalWrite(y2, HIGH);
    delay(15);
    digitalWrite(y2, LOW);
    digitalWrite(y3, HIGH);
    delay(15);
    digitalWrite(y3, LOW);
    digitalWrite(y4, HIGH);
    delay(15);
    digitalWrite(y4, LOW);
    digitalWrite(y5, HIGH);
    delay(15);
    digitalWrite(y5, LOW);
    digitalWrite(y6, HIGH);
    delay(15);
    digitalWrite(y6, LOW);
    digitalWrite(x5, LOW);
    digitalWrite(x6, HIGH);
    digitalWrite(y1, HIGH);
    delay(15);
    digitalWrite(y1, LOW);
    digitalWrite(y2, HIGH);
    delay(15);
    digitalWrite(y2, LOW);
    digitalWrite(y3, HIGH);
    delay(15);
    digitalWrite(y3, LOW);
    digitalWrite(y4, HIGH);
    delay(15);
    digitalWrite(y4, LOW);
    digitalWrite(y5, HIGH);
    delay(15);
    digitalWrite(y5, LOW);
    digitalWrite(y6, HIGH);
    delay(15);
    digitalWrite(y6, LOW);
    digitalWrite(x6, LOW);

  }
}

The concepts which will help you are  for loops and possibly arrays.

Definitely arrays. Any idea how I get the Code smaller? - why does it need to be smaller? It fits into available memory, or it doesn't.

Any idea how I get the Code smaller?

don't try to get the code smaller -> try to get it working.
for things like this, you should think about
1) how to structure the display data: typically it is done in a matrix format. I would structure it as an array of 6 chars / columns, with the rows in the lowest 6 bits;
2) how to track the column being displayed and updated: using a static variable typically;
3) how to update the display periodically: via a timer interrupt usually.
Each update would go something like this:
  turn off all columns;
  present row information;
  update the column index and turn it on;

what's left is to implement that in a way that the code is flexible and portable to a different application.
once that's done, all your application needs to do is to stuff the right information into the display buffer and the display routine, invoked via a timer isr, will take care of the updating all by itself, without user involvement.
if you still need help, let us know.
edit: i put this together quickly to demonstrate the concept.
it is a display routine, led_display(), being invoked via a timer2 interrupt, displaying data in an 8-char buffer, 0x11, 0x22, ..., 0x88.
the scanning is done by colomn (active high), and the rows are connected to D0..D7, and the cols D8..D13, A0, A1, all user configurable.
//global variables
uint8_t lRAM[COL_NUM]={         //display buffer
    0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88
};

const uint8_t row_pins[ROW_NUM]={   //pins tied to matrix' rows
    0, 1, 2, 3, 4, 5, 6, 7,
};

const uint8_t col_pins[COL_NUM]={   //pins tied to columns
    8, 9, 10, 11, 12, 13, A0, A1,
};

once the initialial set-up is done, there is nothing the user needs to do, other than filling the display buffer with information s/he wishes to be displayed.
void setup() {
    // put your setup code here, to run once:
    //pinMode(led, OUTPUT);
    led_init();                         //reset the led module

    //set up timer2
    tmr2_init(TMR2PS_32x);              //timer2 with 32:1 prescaler -> 16Mhz / 256 / 32 = 2Khz per col.
    tmr2_act(led_display);              //install user handler to update the display periodically
}

void loop() {
    // put your main code here, to run repeatedly:
    //digitalWrite(led, HIGH);  // turn the LED on (HIGH is the voltage level)
    //delay(100);               // wait for a second
    //digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
    //delay(100);               // wait for a second
}

and here is the execution.
ps: the code was originally written to drive 8x7-segment displays but it works with 8x8 matrix as well -> they are essentially the same thing.
the display routine, led_display(), follows the general sketch laid out earlier.
//update the display
void led_display(void) {
    static uint8_t col_index=0;         //current col
    //turn off current col -> the only active col now
    COL_OFF(col_pins[col_index]);

    //update the column index
    col_index=(col_index==COL_NUM-1)?0:(col_index+1);

    //present row data
    if (lRAM[col_index] & (1<<0)) ROW_ON(row_pins[0]); else ROW_OFF(row_pins[0]);
    if (lRAM[col_index] & (1<<1)) ROW_ON(row_pins[1]); else ROW_OFF(row_pins[1]);
    if (lRAM[col_index] & (1<<2)) ROW_ON(row_pins[2]); else ROW_OFF(row_pins[2]);
    if (lRAM[col_index] & (1<<3)) ROW_ON(row_pins[3]); else ROW_OFF(row_pins[3]);
    if (lRAM[col_index] & (1<<4)) ROW_ON(row_pins[4]); else ROW_OFF(row_pins[4]);
    if (lRAM[col_index] & (1<<5)) ROW_ON(row_pins[5]); else ROW_OFF(row_pins[5]);
    if (lRAM[col_index] & (1<<6)) ROW_ON(row_pins[6]); else ROW_OFF(row_pins[6]);
    if (lRAM[col_index] & (1<<7)) ROW_ON(row_pins[7]); else ROW_OFF(row_pins[7]);

    //turn on the display
    COL_ON(col_pins[col_index]);
}

The problem is, that im not allowed to change something in the circuit. I am only coding it for a good Friend how allready solder it. The Circuit works and i have to programm some Programms for it :) Something like waves or circles.

if I understand something wrong correct me :D Im not so good in English

It is maybe possible to make a routine wich is going in the background and you can putt some pattern in it? if yes can you help me programm it :) I dont know much about c & c++

obviously people will be willing to help you but you have to get it started somewhere. no one is going to write the code for you.

You can use arrays to hold sets of row pin numbers or column pin numbers, which then allows use of for loops for pinMode() settings and for testing LEDs one after another, as shown in code below.
Note, using enum { ... }; for integer-constant declarations is slightly more compact than a series of const int statements.  When a constant name in an enum does not have an = and value after it, it is given a value one larger than the previous constant.  So, for example, the first enum in the following code sets x2 to 3, x3 to 4, etc.
enum { x1=2, x2, x3, x4, x5, x6};
enum { y1=8, y2, y3, y4, y5, y6};
const byte rowPins[] = { x1, x2, x3, x4, x5, x6};
const byte colPins[] = { y1, y2, y3, y4, y5, y6};
enum { nRow = sizeof rowPins / sizeof rowPins[0] };
enum { nCol = sizeof colPins / sizeof colPins[0] };

void setup() {
  for (byte i=0; i<nRow; ++i) pinMode(rowPins[i], OUTPUT);
  for (byte i=0; i<nCol; ++i) pinMode(colPins[i], OUTPUT);
  for (byte i=14; i<18; ++i)  pinMode(i, INPUT);
}

void loop() {
  byte test = digitalRead(17);
  if (test) {
    for (byte x=0; x<nRow; ++x) {
      digitalWrite(rowPins[x], HIGH);
      for (byte y=0; y<nCol; ++y) {
        digitalWrite(colPins[y], HIGH);
        delay(15);
        digitalWrite(colPins[y], LOW);
      }
      digitalWrite(rowPins[x], LOW);
    }
  }
}

Note, subroutines and functions can be used to modularize code and (typically) reduce its volume.  See code sample below.  In the code as is, the subroutine doesn't particularly reduce volume, but definitely adds modularity.  You may find it useful to look up refactoring.
enum { x1=2, x2, x3, x4, x5, x6};
enum { y1=8, y2, y3, y4, y5, y6};
const byte rowPins[] = { x1, x2, x3, x4, x5, x6};
const byte colPins[] = { y1, y2, y3, y4, y5, y6};
enum { nRow = sizeof rowPins / sizeof rowPins[0] };
enum { nCol = sizeof colPins / sizeof colPins[0] };

void setup() {
  for (byte i=0; i<nRow; ++i) pinMode(rowPins[i], OUTPUT);
  for (byte i=0; i<nCol; ++i) pinMode(colPins[i], OUTPUT);
  for (byte i=14; i<18; ++i)  pinMode(i, INPUT);
}

void lightup(byte x, byte y, unsigned int howLong) {
  digitalWrite(rowPins[x], HIGH);
  digitalWrite(colPins[y], HIGH);
  delay(howLong);
  digitalWrite(colPins[y], LOW);
  digitalWrite(rowPins[x], LOW);
}

void loop() {
  byte test = digitalRead(17);
  if (test) {
    for (byte x=0; x<nRow; ++x)
      for (byte y=0; y<nCol; ++y)
        lightup(x, y, 15);
  }
}


text:
Arduino Nano TX LED is on
My Arduino nano make weired thing...
The TX LED is on when i define a Variable and a digital Pin as output. Do you now if it is a error in the code? If I upload a clear new sketch the LED is off.
~Nico
Code:

int ok = 1;
int err = 0;
int x1 = 2;
int x2 = 3;
int x3 = 4;
int x4 = 5;
int x5 = 6;
int x6 = 7;
int y1 = 8;
int y2 = 9;
int y3 = 10;
int y4 = 11;
int y5 = 12;
int y6 = 13;
int value1 = digitalRead(14);
int value2 = digitalRead(15);
int value3 = digitalRead(16);
int test = digitalRead(17);

void setup() {
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(14, INPUT);
  pinMode(15, INPUT);
  pinMode(16, INPUT);
  pinMode(17, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

}

You configure serial pins as output, this may be your issue.

also, you're calling some digitalRead() before setup call, you would have to do that in the loop.

I tried some things to the pins and i foud something very interessting out. The value to be activated must be LOW instead of HIGH. That means that the TX and RX pins can be used as a normal digital pin but the activation value is inverted. I made a short video where I tested it. It is unlisted on YouTube: link     ~Nico

So... My decision was WRONG. The LED's in the Arduino are on if the pins are off. If the pins are on the LED's are off. For some reason the RX pin is on if you made him to an digital output. Would be awesome if some other people test it too to check if it is only for me or if it in a error of the Arduino Nano.  ~Nico

Both RX & TX pins are driving the onboard LEDs when set to LOW. Those 2 pins are tied to FT232RL chip to convert serial signal for USB. This may be the reason they are reacting to inverted logic. If you can avoid using these 2 pins, it would be better. you could also reflash the nano without disconnecting it from your own electronic parts for those 2 pins (reflashing may not work depending on what is connected on these pins).


text:
Forwarding serial output from a Nano to Uno that's used as the ISP
I'm trying to program a Nano by using an Uno as the ISP. So far, I've followed along with the example project for getting the Uno running as the ISP on https://www.arduino.cc/en/Tutorial/ArduinoISP.
After a bit of tinkering, it works, but the serial monitor won't work correctly. I'm uploading a super simple program that delays for 500 ms and prints to the log.
void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("test");
  delay(500);
}

I've wired the TX pin on the Nano to the RX pin on the uno. The monitor updates every 500 ms as expected after doing so, but displays ��� instead of the word test. When I tried wiring TX -> TX, the serial monitor does not update. Does anyone have any insight what's missing here?

You can't really connect an ordinary Arduino's serial pins to both another device and the on-board USB serial converter at the same time.  You'd probably do best to use a separate USB serial converter for the target, otherwise you need to use software serial (or better a chip with a 2nd hardware port) and add some sort of selectable pass-through mode to your ISP sketch.  Possible, but not easy, try using the separate converter instead.

@ChrisStratton gotcha, thank's for the explanation. I tried to use the mini usb to connect the nano, but my computer doesn't seem to recognize it. It was still fun to learn about ISPs though

Can you try by writing on the uno a program to set the TX and RX pins as inputs? Just something like void setup() { pinMode(0, INPUT); pinMode(1, INPUT); } void loop() {}, then repeat again the test (I think you'll have to connect the nano TX to TX and nano RX to RX)

As Chris Stratton suggests in his comment above:

You can't really connect an ordinary Arduino's serial pins to both another device and the on-board USB serial converter at the same time.

To solve your serial monitor problem use a separate USB serial converter and connect that to your Arduino Nano.
If you don't have access to a dedicated USB serial converter you could use software serial on the Arduino Nano. This allows you to connect the Arduino Uno Rx pin to the software serial Tx pin. You will also need to program the Arduino Uno with a program that re-transmits the data it receives back out to the PC serial monitor.


text:
ESP8266 unstable connection
I try to flash an ESP12E microcontroller through an FTDI serial converter. It seems like the UART connection is a bit unstable, because when I try to flash it via esptool it often throws "Timed out waiting for packet header" error. Also when I thy to get the flash_id the same error occures at around 50% of the time. The simplier commands like get_mac and chip_id are working well.
I'm using an ESP module with wires soldered to its pads. It is put into a breadboard and it's connected to a USB-UART converter via jumper wires.
What could be the problem?

I have several 4 x ESP07's, 2 x ESP12E's and 14 x ES12F's ... the 07's and 12F's never give me problems, however, the two 12E's are unstable as hell when using FTDI, even flashing OTA whilst powered by FTDI cable is a 50/50 proposition - ditch the 12E's get some 12F's is my advice

Power supply...
I designed a pcb for the ESP module, it works like a charm since then. Used a TC1262 regulator, a 100n ceramic and a 1000u electrolyte capacitor (maybe 100u would have been enough) very close to the Vcc and GND pins.
Seems like the ESP is really sensitive to the power supply stability.

authors: מוחמד אבו פודה


text:
How to ground a arduino with an external power-source?
I have magnet hooked up to my arduino with a Darlington Transistor, like this:

The powersource is a 12V adapter
I'm pretty new to electronics but i'm told that the transistor won't work unless the ground on the arduino is the same as the ground on the external source. How do I do this in practice? Should I run a wire from the ardunio-ground to the negative pole on the powersource? How do I tell which one is the negative one?

Ground is usually (though not always, but in your case it is) the point of lowest potential in a circuit. In your circuit that is the "negative" connection of the power supply. Note that the "negative" isn't actually "negative", it is zero volts when measured from the reference point of itself.
So yes, you need to know which is the "negative" connection and connect that to ground on the Arduino.
Since you already have it wired up the negative is the one which connects to the emitter of your transistor. If you don't know which that is and you just randomly connected a random wire to a random pin then you need to investigate your power supply.
The simplest way is with a Digital MultiMeter (one of the most basic items you need to own if you are working with electronics - if you don't have one then go and buy one immediately). Set it to DC Volts in the right range then connect the two probes (correctly inserted into the right sockets on the DMM) to the power supply's output connections. If the voltage reads positive then the black probe is connected to negative. If it reads a negative value then the red probe is connected to negative.
If you cannot get a DMM but you have an LED (note: a bulb will not work) and a suitable resistor (say 2.2K) you can connect the resistor in series with the LED then connect the two to the power supply. The cathode of the LED (the pin with the flat side on the case) connects to negative. Connect the power both ways round. The way round that it lights the LED is the correct way round, and you know that the connection that goes to the cathode (flat side of the lip round the bottom of the LED) is the negative.

“Since you already have it wired up the negative is the one which connects to the emitter of your transistor”  – What's that mean?  Anyhow, for a grounded-emitter low-side switch, either the battery or the transistor in the diagram in the question is backwards, an issue you might address with a correct diagram in your answer.

I would be careful about "ground loops" when using two supplies connected to the mains electricity. You may get strange results. If you are using a lap top then maybe disconnect it from the charger while the PSU is plugged in the wall. Or use a battery for your coil. Or power the Arduino from a power bank. Or get a 12v USB adaptor and power the arduino from the 12v supply. Add and LED for debugging while connected to the computer. Then disconnect from the computer and plug in the 12v supply.

very useful info!

Majenko explained how to figure out what is what. I'm just repeating the shematics again with "additional" description:

Current limiting resistor R1 is REQUIRED, if you don't want to destroy Arduino output by over current.
About using the LED to test your power source polarity:

And again, current limiting resistor is required, or you'll burn it. As Majenko stated, it should be about 2k2.


text:
How is this simple transistor circuit suppose to work?
I've tried to replicate this circuit today.

My motor is a computerfan, they apperntly don't need a flyback diode since there are no brushes.
I used a 12V power source for my arduino and hooked it up via
VIM.
I used the arduino ground as external power source.
I verified that the transistor worked as expected with a voltmeter.

Here is the transistor I used:
As I understand this, the transistor is stimulated to "steal" electrons away from the motors circuit. But it seems connected to the base. Why would you do that?

Not all transistors have the same pinout. How do you know what transistor is used in that drawing?

An answer may be found here: https://www.arduino.cc/en/Tutorial/TransistorMotorControl

The circuit might be totally wrong. Where does it come from?

It seems like it is wrong, it's from a magnetic stirrer tutorial https://www.hackster.io/jdale18/magnetic-stirrer-88e726

@Himmators Thanks. Google picture search could not find the original picture. They use a tip31a, which has the pin in BCE order and is for a maximum current of 3 amps, that is more than the 100 milliamps of the bc548. They have forgotten a resistor to the base of the transistor.

There are many bad schematics and pictures online, and these pictures are really bad.
Do not try to make that. You may damage the Arduino board and the transistor.

Even the picture of the BC548 is wrong. The BC548 is always
called "BC548" and never "BC-548".
The BC548 is not a good choice to drive a motor. It can only
do 100 mA continuous.
The DC barrel socket has plus and minus wrong connected.
The 12V plus is connected to the Arduino GND.
That is not okay.
The transistor in the first picture is probably a
transistor with the pins in BCE order.
A resistor is missing to the base of the transisor.
Because of the missing resistor, the Arduino board
can be damaged.
When the breadboard has a bad connection to GND,
the 12V can go to pin 9 of the Arduino board.

@Dorian, there are no mystical higher alien intelligent thoughts for that schematic. It is obvious a wrong circuit that is meant to drive a motor with PWM using a transistor.
And last but not least:
There are a few different types of computer fans. Some have a capacitor inside and some will only accept a PWM signal to a PWM input.
Are you sure that your fan is able to accept PWM for the 12V power?

Wow, I sure learned a lesson here! I have a basic fan witout a PWM input, so the plan is to regulate the speed of the fan by changing the voltage. I tried this with a powercube and it seems to work fine :)

@Himmators please tell us what you want to do so we can help. You can add that to your question. Do you have a mosfet? A diode is always good, even if it might seem that it is not needed.

This looks like a circuit to monitor the power loss in the motor supply. If the motor is powered and the circuit is not interrupted then the collector will poll Arduino pin 9 to GND.


text:
Will a transistor always reduce the voltage?
I have an NPN transistor that's connected over a 12V adapter. I have tried using a potentiometer to change the resistance of the incomming current. Even if i take the resistance down to 0, I end up with at most 11 Volts when measuring over the magnet.
I have measure the energy without the transistor, in that case it's 12V. Is this expected behaviour of a transistor or is something wrong?

I'm voting to close this question as off-topic because it has nothing to do with Arduino and should be posted on EE.SE. There isn't even the word "Arduino" once in the question.

Yes, it is, as both VCE(sat) and the "Collector-Emitter Saturation Voltage vs Collector Current" chart in the datasheet tells you.

By context I'm assuming "yes it is expected behaviou"

1V seems a bit high. But since we don't know the current through the electromagnet, or the transistor, or the base-resistor, it might well be true.

@Himmators the actual vales in datasheet depend on your specific transistor -which you didnt state in this question


text:
Why is my transistor always transmitting?
I want to use a transistor to turn on and of an electric magnet, I have hooked up a transistor like this:

simulate this circuit – Schematic created using CircuitLab
The blue wire goes to the magnet and the white wire goes to the ground:

Regardless of if the arduino is on or off(I can even unplug port 12 from the arduino, the magnet is still on, the circuit never closes. What do I need to do to make the transistor turn off?

If you detach the base connection to the Arduino, it must close then. If not, you have reversed power source and the internal anti-parallel diode is opened. Or you've already destroyed your transistor.

What is the part number? TIP120? Sounds to me like a transistor with a different pinout.

Don't forget the freewheeling diode across the coil.

Did you make the electromagnet your self?If so some magnets will retain their magnetism for long time making it appear your circuit is not off. If you raplidy switch on or off too quickly may look like its on because it may retain magnetism

@Gerben, yes TIP120, https://cdn-shop.adafruit.com/datasheets/TIP120.pdf .

Looks like you connected it the right way around.

@Gerben Right way around = No need to change?

Sorry for the confusion. I you connected if perfectly. So that can't be the problem.

Darlington transistors are very sensitive; even putting your hand near it can be enough to turn it on. Either tie the base to ground with a large resistor or switch to a MOSFET with its gate tied to ground through same. In either case put a diode backwards across the coil to absorb the energy from the coil when it de-energizes so that the transistor is not damaged.

Could you suggest a good MOSFET-transistor for a 12V magnet?

I would recommend going to the web site of a distributor such as DigiKey or Mouser and using their parametric search tool to find an appropriate device.

@Himmators You dont need to MOSFET it, it  will work with a tip 120 if you build the circuit, using TIP 120, correctly. The darlington is "sensitive" to your hand, which really isnt a problem . Its sensitive because it has high gain- high gain is  useful  for driving something like an electromagnet.

@DatHanBag, thanks! Do you have any idea what might cause the problem?

@Himmators You may have damaged the TIP 120 transistor for some reason- since you need a dioide in the first place-as Edgar wrote above. I would start with a new TIP120 with the diode to protect it,  Tie the base to ground as its says in the answer-this is important. Make sure your circuit is correct. If your base resistor is too low it wont work properly too-so try base resitor values from 10k -maybe as low as 4K will work.


text:
How to calibrate a PID?
I'm working on a pid-controlled levitating magnet device. It uses a hall-sensor to turn on and off an electro magnet in ordet to achieve levitation.
When I hold a magnet close to the hallsensor, I can sense a pulsation from the electro-magnet, however, I if let go of the magnet, it always sticks to the electro-magnet every time, as though the pid is not properly calibrated, the code i'm using came with a pre built possibility to calibrate the PID, you can change set point, Proportion, integral and derivative I've tried messing with it, but it doesn't seem to make any difference.
/*
   Magentic Levitation

   1) connect the digital pin PIN_COIL to the MOSFET gate for electromagnet activation.
   2) connect the analog input pin PIN_HALL_SENSOR to the hall sensor signal pin (the other
      two pins shall be wired to gnd and +5V).
   3) (optional) connect the digital pin PIN_CTRL_INDICATOR to the LED that indicates when the
      controller loop is running.
   4) run Arduino, on the serial port the following commands are available:
      - press 's' or 'S' to decrease or increase the setpoint,
      - press 'p' or 'P' to decrease or increase the P gain,
      - press 'd' or 'D' to decrease or increase the D gain,
      - press 'i' or 'I' to decrease or increase the I gain,
      - press 'x' or 'X' to show the current settings
   5) the system enters in IDLE mode, with a minimum PWM command that allows the orientation of the
      permanent magnet, when in range the system goes in CONTROL mode. When the magnet is too close to
      the coil, the system switches in OFF mode by turning off the PWM command.

   version 1.0: 23/12/2011 -  E.Assenza
*/

const int PIN_COIL = 11; // Pins 3 and 11 are connected to Timer 2.
const int PIN_HALL_SENSOR = 0;
const int PIN_CTRL_INDICATOR = 13;
// Coil resistance 3 ohm, max 1 A = 3 Volt max.
const int COIL_MAX_PWM_VALUE = 160;
// Minimum magnetic field when in idle mode (needed to properly orientate the magnet).
const int COIL_IDLE_VALUE = 50;
// Proximity thresholds, when the magnetic field is in this range enters in control mode.
const int MAG_PROX_THRESHOLD_MIN = 585;
const int MAG_PROX_THRESHOLD_MAX = 615;
// Magnetic field limits, when outside this range enters in idle mode.
const int MAG_LIMIT_MIN = 560;
const int MAG_LIMIT_MAX = 700;
// Control loop frequency.
const int CTRL_LOOP_PERIOD_MS = 1;
// Control loop bias value (PWM midpoint)
const int CONTROL_BIAS = 65;
// Set point corresponding to the control bias
const int CONTROL_SETPOINT = 597;
const int MAX_ERR_INTEGRAL = 10000;
// PID controller parameters
const float PGain = 2.1;
const float DGain = 23.6;
const float IGain = 0.001;

const float P_INCR = 0.1;
const float D_INCR = 0.1;
const float I_INCR = 0.001;

// State machine constants.
const byte MODE_OFF = 0;
const byte MODE_IDLE = 1;
const byte MODE_CONTROL = 2;

const char     *gAppName = "Arduino Magnetic Levitation";
byte            gMode;
int             gSetPoint;
int             gSensorReadout;
int             gPrevSensorReadout;
int             gPwmCommand;
int             gIntegral;
float           gBias;
float           gP;
float           gD;
float           gI;
unsigned long   gMillisCounter;

void setupCoilPWM()
{
   // Setup the timer 2 as Phase Correct PWM, 3921 Hz.
   pinMode(3, OUTPUT);
   pinMode(11, OUTPUT);
   // Timer 2 register: WGM20 sets PWM phase correct mode, COM2x1 sets the PWM out to channels A and B.
   TCCR2A = 0;
   TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
   // Set the prescaler to 8, the PWM freq is 16MHz/255/2/<prescaler>
   TCCR2B = 0;
   TCCR2B = _BV(CS21);
}

void writeCoilPWM(uint8_t pin, int val)
{
   if( pin == 3 )
   {
      OCR2B = val;
   }
   else if( pin == 11 )
   {
      OCR2A = val;
   }
   else
   {
      OCR2A = 0;
      OCR2B = 0;
   }
}

void processCommand( int cmd )
{
   char tmp[64];

   switch(cmd)
   {
      case 'p':
         gP -= P_INCR;
         if( gP < 0 ) gP = 0;
         break;
      case 'P':
         gP += P_INCR;
         break;
      case 'd':
         gD -= D_INCR;
         if( gD < 0 ) gD = 0;
         break;
      case 'D':
         gD += D_INCR;
         break;
      case 'i':
         gI -= I_INCR;
         if( gI < 0 ) gI = 0;
         break;
      case 'I':
         gI += I_INCR;
         break;
      case 's':
         gSetPoint --;
         break;
      case 'S':
         gSetPoint ++;
         break;
      case 'x':
      case 'X':
         sprintf(tmp, "s(%d) c(%d) h(%d) P(%u) D(%u) I(%u,%d)\n", gSetPoint, gPwmCommand, gSensorReadout, (uint16_t)(gP*1000.0), (uint16_t)(gD*1000.0), (uint16_t)(gI*1000.0), gIntegral );
         Serial.print(tmp);
         break;
      default:
         break;
   }
}

byte executeOffMode()
{
   digitalWrite(PIN_CTRL_INDICATOR, LOW);

   // turn off magnetic field
   gPwmCommand = 0;
   writeCoilPWM(PIN_COIL, gPwmCommand);

   gSensorReadout = analogRead(PIN_HALL_SENSOR);

   if( gSensorReadout <= MAG_LIMIT_MIN )
   {
      // Switch to idle mode.
      return MODE_IDLE;
   }
   else
   {
      return MODE_OFF;
   }
}

byte executeIdleMode()
{
   digitalWrite(PIN_CTRL_INDICATOR, LOW);

   // Apply minimum magnetic field.
   gPwmCommand = COIL_IDLE_VALUE;
   writeCoilPWM(PIN_COIL, gPwmCommand);

   gSensorReadout = analogRead(PIN_HALL_SENSOR);

   if( (gSensorReadout >= MAG_PROX_THRESHOLD_MIN) && (gSensorReadout <= MAG_PROX_THRESHOLD_MAX) )
   {
      // Switch to control mode.
      gIntegral = 0;
      return MODE_CONTROL;
   }
   else if( gSensorReadout > MAG_LIMIT_MAX )
   {
      return MODE_OFF;
   }
   else
   {
      return MODE_IDLE;
   }
}

byte checkOutOfLimits(int val)
{
   if( val <= MAG_LIMIT_MIN )
   {
      return MODE_IDLE;
   }
   else if( val >= MAG_LIMIT_MAX )
   {
      return MODE_OFF;
   }

   return MODE_CONTROL;
}

byte executeControlMode()
{
   int err;
   int der;

   byte mode = MODE_CONTROL;

   // Execute control loop at frequency = 1/CTRL_LOOP_PERIOD_MS.
   if( (signed long)( millis() - gMillisCounter ) >= 0)
   {
      gMillisCounter = millis() + CTRL_LOOP_PERIOD_MS;

      digitalWrite(PIN_CTRL_INDICATOR, HIGH);

      gPrevSensorReadout = gSensorReadout;

      // Read hall sensor.
      gSensorReadout = analogRead(PIN_HALL_SENSOR);

      // Check if out of limits (the magnet is out of coil range).
      if( (mode = checkOutOfLimits(gSensorReadout)) != MODE_CONTROL )
      {
         return mode;
      }

      err = (gSetPoint - gSensorReadout);
      der = (gPrevSensorReadout - gSensorReadout);
      gIntegral += err;
      gIntegral = constrain( gIntegral, -MAX_ERR_INTEGRAL, MAX_ERR_INTEGRAL);

      gPwmCommand = gBias + (int)(gP*err) + (int)(gD*der) + (int)(gI*gIntegral);

      gPwmCommand = constrain( gPwmCommand, 0, COIL_MAX_PWM_VALUE);

      // Apply output.
      writeCoilPWM(PIN_COIL, gPwmCommand);

      // Write data to serial port.
/*      Serial.write( (uint8_t)0xAF );
      Serial.write( (uint8_t)gSetPoint );
      Serial.write( (uint8_t)(gSetPoint >> 8) );
      Serial.write( (uint8_t)gSensorReadout );
      Serial.write( (uint8_t)(gSensorReadout >> 8) );
      Serial.write( gPwmCommand );
   }

   return mode;
}

void setup()
{
   setupCoilPWM();

   pinMode(PIN_CTRL_INDICATOR, OUTPUT);

   Serial.begin(115200);

   gMillisCounter = 0;
   gMode = MODE_IDLE;
   gSetPoint = CONTROL_SETPOINT;
   gBias = CONTROL_BIAS;
   gSensorReadout = 0;
   gIntegral = 0;
   gP = PGain;
   gD = DGain;
   gI = IGain;
}

void loop()
{
   // User commands.
   if( Serial.available() )
   {
      processCommand( Serial.read() );
   }

   // State machine.
   switch( gMode )
   {
      case MODE_OFF:
         gMode = executeOffMode();
         break;

      case MODE_IDLE:
         gMode = executeIdleMode();
         break;

      case MODE_CONTROL:
         gMode = executeControlMode();
         break;

      default:
         break;
   }
}

Robotics Stackexchange is more suitable for questions like this.

PIDs are reasonably on-topic here. Is the question specifically about robotics?

How about telling us the value of gPwmCommand while running your code? There also a possibility that the error is not because of your code, but your electronics.

@NickGammon, I'm inclined to disagree that tuning a PID is on-topic here (but nevertheless won't vote to close as off-topic).  Also, I think PID expertise is stronger in R.S.E than here.

If the OP requests it, I will migrate to Robotics.

as @dpw says, It's possible that it's not actually the PID that is the problem, that's why I posted here. Either way i'm very happy with the answer son if you want to keep this on your(our) awesome site, i'd be glad to have it here!

You likely need to tune the limits the control applies before you can tune the PID.  I.e.: MAG_PROX_THRESHOLD_MIN/MAG_PROX_THRESHOLD_MAX and MAG_LIMIT_MIN/MAX.  If those aren't set correctly for your particular device & magnet, then the PID within those ranges might not help you.

Gidday!  First response as a new member.  PID control is not an easy subject to grasp for starters but here is a link to a site that does explain it:
http://www.csimn.com/CSI_pages/PIDforDummies.html
The first thing about your project is that your output is digital (HIGH/LOW) whereas traditionally PID control is analog.  AnalogIN to PID to AnalogOUT. So ideally you would need to vary the current through an electromagnet and have the hall-effect make very quick updates (feedback) to the PID controller. Now most young engineers (armed with some maths) learn to control the level of a tank (water or chemical or whatever) and yes, they follow a calibration method.  The P is done first and this is the GAIN of the system the Integral usually follows & this is like a 'speed of response' type of adjustment. (Derivative rarely used).
I'm guessing your levitation system would require and extremely fast response & I think it would suffer from:

The time of the Analog to digital conversion at the input to the PID
The speed of the Arduino to process the code it runs
The time it takes for the OUTPUT to be applied to the electromagnet (e.g. the PWM updates inside the Arduino if you decided to use this as a pseudo 'analog output').

I know this is not good news for you but don't give up as someone will have found a work-around to this problem I'm sure.  It just seems like a bit more research is required.  Maybe some other members can assist further.

Thanks for the clarification. I must admit that I could never totally get PIDs to work properly, particularly with the derivative part. Saying it is rarely used helps to concentrate on the more important parts.

this is a really nice, very extensive answer. I was thinking about that analog PID might be better aswell. My project is a reproduction of an existing project: https://forum.arduino.cc/index.php?topic=89241.0 so I don't think the design is the problem, it's probably something with my implementation. For example, how short long wires would start causing a problem?

Well, the response time should not be a major issue, since the ball movement is based solely on the acceleration due to gravity and the magnetic force due to the coil. If you let the ball free fall from being stopped, it would take 14.3 ms for it to move the first 1 mm, and that is a lot of time for computing and for electrical circuits to respond.
To calibrate the PID, a process usually called PID tuning, you would start with the proportional constant, Kp. Since your system is unstable, that is, without the PID either the ball will fall or stick to the electromagnet, it will be hard to tune the Kp, even with minor errors on your hall sensor readings. If the position error is large or the sensor takes too much time to update, that can also complicate the tuning.
You should check the furthest away the ball can be and still be drawn to the magnet, that point is the limit where your PID can save the ball from falling. As a rule of thumb, try tuning the Kp with the setpoint being in between the magnet and that point. At first you want just the Kp being non-zero, and it should have a value great enough so that, if the ball falls a little bit bellow the setpoint the magnet is fully powered and if it goes a bit over the setpoint the magnet turns off. This should lead to the ball oscillating around the setpoint. This method will work on your system because the output is limited between a PWM with duty 100% and 0% (you can change these limiting values if needed!), (I suppose) turning the coil to its maximum and minimum doesn't damage the system and the system is relatively slow (the gravity effect is always the same and the acceleration due to the magnet depends on the mass of the ball).
After you got it to work so-so, try lowering the Kp to the minimum value that keeps the ball oscillating around the setpoint and then read on Ziegler–Nichols tuning method.

When I hold a magnet close to the hallsensor, I can sense a pulsation from the electro-magnet, however, I if let go of the magnet, it always sticks to the electro-magnet every time, as though the pid is not properly calibrated,

That behavior is odd, even a bad PID should eventually turn off the magnet after detecting the ball went above the setpoint. Maybe the sensor reading is causing the problem, e.g. the ball goes close to the magnet but the sensor/code interpret it as going away from the magnet.