John Hufnagel
Gray_code_element
Tuesday, June 10, 2025
Wednesday, May 21, 2025
Using ESP32 for HTTPS
#include <WiFi.h> #include <WiFiClientSecure.h> const char* ssid = "yourSSID"; const char* password = "yourPassword"; const char* host = "script.google.com"; const int httpsPort = 443; // Optional: root certificate for Google (you can skip this in testing) const char* root_ca = \ "-----BEGIN CERTIFICATE-----\n" \ "...Google's root cert here...\n" \ "-----END CERTIFICATE-----\n"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("Connected."); WiFiClientSecure client; client.setInsecure(); // or use: client.setCACert(root_ca); if (!client.connect(host, httpsPort)) { Serial.println("Connection failed"); return; } String url = "/macros/s/your-script-id/exec?sheetName=Sheet1&row=5&col=1&value=FromESP32"; client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); while (client.connected()) { String line = client.readStringUntil('\n'); Serial.println(line); } } void loop() {}
Google Sheet Update from HTTP POST
The following code will update a Google sheet:
function doGet(e) { // This function handles GET requests (for simplicity in this example) // Get parameters from the URL var sheetName = e.parameter.sheetName; var row = parseInt(e.parameter.row); var col = parseInt(e.parameter.col); var value = e.parameter.value; // Basic error handling if (!sheetName || isNaN(row) || isNaN(col) || value == = undefined) { return ContentService.createTextOutput("Error: Missing parameters (sheetName, row, col, value)").setMimeType(ContentService.MimeType.TEXT); } try { // Get the spreadsheet and the specific sheet var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName(sheetName); if (!sheet) { return ContentService.createTextOutput("Error: Sheet not found: " + sheetName).setMimeType(ContentService.MimeType.TEXT); } // Update the specified cell (row and column are 1-based) sheet.getRange(row, col).setValue(value); return ContentService.createTextOutput("Cell updated successfully! Sheet: " + sheetName + ", Row: " + row + ", Col: " + col + ", Value: " + value).setMimeType(ContentService.MimeType.TEXT); } catch (error) { return ContentService.createTextOutput("Error: " + error).setMimeType(ContentService.MimeType.TEXT); } }
Apparently, I can write to google sheets just using a URL
You're on the right track, but the mechanism isn't a direct HTTP POST to a standard Google Sheets URL. Instead, you leverage Google Apps Script to create a web application that receives HTTP POST requests and then writes the data into your Google Sheet.
Here's a breakdown of how it works:
1. Google Apps Script:
- You write a script within Google Sheets (Tools > Script editor).
- This script will contain a function that is designed to:
- Accept HTTP POST requests.
- Parse the data sent in the request (e.g., as JSON or form data).
- Use the Google Sheets API (within Apps Script) to write this data into the desired sheet and cells.
- Crucially, you then deploy this script as a web application. This process generates a unique URL that acts as the endpoint for your HTTP POST requests.
2. HTTP POST Requests:
- From your program (using any language that can make HTTP requests, like Python with requests, JavaScript with fetch, etc.), you send an HTTP POST request to the URL generated by your deployed Google Apps Script.
- The data you want to enter into the Google Sheet is included in the body of the POST request. You can format this data in various ways, commonly as JSON or URL-encoded form data.
Why not a direct POST to the Google Sheets URL?
- Security and Permissions: Directly posting data to a standard Google Sheets URL would bypass any security or permission controls. Anyone could potentially write data to your sheet. Google Apps Script allows you to control access and execution permissions for your web app.
- Data Handling and Formatting: Google Sheets expects data to be formatted in a specific way within its grid structure. A direct POST wouldn't inherently know how to interpret arbitrary data and place it correctly in rows and columns. Apps Script provides the logic to parse the incoming data and use the Sheets API to write it in the desired format.
- Logic and Processing: You might want to perform some actions on the incoming data before writing it to the sheet (e.g., data validation, formatting, calculations). Apps Script allows you to implement this logic.
In summary:
You don't directly POST to a Google Sheets URL. Instead, you:
- Create a Google Apps Script that handles POST requests and writes to your sheet.
- Deploy this script as a web application to get a unique URL.
- Send HTTP POST requests to this generated URL from your program, with the data you want to enter in the request body.
This approach provides a secure and controlled way to programmatically write data to Google Sheets using HTTP POST requests. You'll need to write the Apps Script code to handle the incoming data and interact with the Google Sheets service.
C# HTTPS connect to a Google Sheet
using System; using System.Net.Http; using System.Threading.Tasks; public class GoogleSheetsUpdater { public static async Task Main(string[] args) { string webAppUrl = "https://script.google.com/macros/s/...."; string sheetName = "Sheet1"; int row = 5; int col = 1; string value = "UpdatedValueFromCSharp"; // Construct the full URL with parameters string fullUrl = $"{webAppUrl}?sheetName={sheetName}&row={row}&col={col}&value={Uri.EscapeDataString(value)}"; using (HttpClient client = new HttpClient()) { try { // Send a GET request to the web app URL HttpResponseMessage response = await client.GetAsync(fullUrl); // Ensure the request was successful if (response.IsSuccessStatusCode) { string responseContent = await response.Content.ReadAsStringAsync(); Console.WriteLine($"Google Sheets updated successfully. Response: {responseContent}"); } else { Console.WriteLine($"Error updating Google Sheets. Status code: {response.StatusCode}"); string errorContent = await response.Content.ReadAsStringAsync(); Console.WriteLine($"Error details: {errorContent}"); } } catch (HttpRequestException ex) { Console.WriteLine($"An error occurred during the HTTP request: {ex.Message}"); } } Console.WriteLine("\nPress any key to exit..."); Console.ReadKey(); } }
Tuesday, May 6, 2025
Subscript and superscript in SolidWorks:
Saturday, May 3, 2025
Friday, April 11, 2025
Arduino HTTP Request
This worked on April 11, 2025 for an Arduino R4 using the Arduino Desktop IDE on a Windows 11 computer.
Make Sure that the Arduino IDE is updated to the most recent version.
Update the Arduino R4 board package:
- Go to Tools>Board>Board Manager → Search for "Arduino UNO R4" → Install/update to the latest version
#include <WiFiS3.h> // Correct library for UNO R4 WiFi
const char ssid[] = "My_ssid";
const char password[] = "My_password";
void setup() {
Serial.begin(9600);
while (!Serial);
// Connect to WiFi
if (WiFi.begin(ssid, password) != WL_CONNECTED) {
Serial.println("WiFi connection failed!");
while (true);
}
Serial.println("Connected to WiFi!");
// Send HTTP GET request
WiFiClient client;
if (client.connect("jsonplaceholder.typicode.com", 80)) {
client.println("GET /comments?id=10 HTTP/1.1");
client.println("Host: jsonplaceholder.typicode.com");
client.println("Connection: close");
client.println();
}
// Read response
while (client.connected()) {
String line = client.readStringUntil('\n');
Serial.println(line);
}
}
void loop() {}
Thursday, March 6, 2025
Monday, February 10, 2025
SVG: Two arrows with text on the ends
Arrow with Text SVG Using Markers and Text tags
In this tutorial, we’ll see how to use the <marker>
and <marker>
elements in SVG to create an arrowhead and text at the end of a line.
SVG Code
Below is the code to create an arrow and text using an SVG marker:
<svg width="250" height="100" viewBox="0 0 250 100">
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="5" refY="5" orient="auto">
<polygon points="0 0, 10 5, 0 10" />
</marker>
</defs>
<line x1="10" y1="50" x2="180" y2="10" stroke="black" stroke-width="2" marker-end="url(#arrowhead)" />
<text x="195" y="15" fill="red">50N 30°</text>
<line x1="10" y1="50" x2="50" y2="10" stroke="black" stroke-width="2" marker-end="url(#arrowhead)" />
<text x="60" y="15" fill="red">20N 45°</text>
</svg>
Live Example
Here’s how the arrow appears in the browser:
To experiment with SVG, along with CSS and JavaScrip, you can use:
SVG Line with Arrow head (marker)
How to Create an Arrowhead in SVG Using Markers
In this tutorial, we’ll see how to use the <marker>
element in SVG to create an arrowhead at the end of a line.
SVG Code
Below is the code to create an arrow using an SVG marker:
<svg viewBox="0 0 100 100" width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- A marker to be used as an arrowhead -->
<marker
id="arrow"
viewBox="0 0 10 10"
refX="5"
refY="5"
markerWidth="10"
markerHeight="10"
orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
</defs>
<!-- A line with a marker -->
<line
x1="10"
y1="10"
x2="80"
y2="80"
stroke="black"
stroke-width="2"
marker-end="url(#arrow)" />
</svg>
Live Example
Here’s how the arrow appears in the browser:
Some notes on using the 'viewBox' property:
The
viewBox="minX minY width height"
determines how the internal coordinates (e.g.,x
,y
,width
,height
of the<rect>
) map to the actual display size (width
andheight
of the<svg>
element).
To experiment with SVG, along with CSS and JavaScrip, you can use:
y bar
y + hold Alt, type 0773
-
In a regular annotation note, create a stack that looks the way you like. It will take a couple of trial and error attempts since there...
-
Getting into Equation Mode use <alt> and = to get into the equation editor. Radicals : $\sum_{i=0}^n i^2 = \frac{(n^2+n)(2n+1)}{6}$ ...