* feat(design): redesign das páginas internas no novo design system Padroniza todas as páginas e componentes internos nos tokens e primitivos de app/globals.css, com contraste AAA (7:1) nos dois temas e alvos de toque de 44px. - Páginas reescritas: glossário, séries, série, seletor, comparador, diagnóstico, catálogo, component registry, frameworks, framework, sobre e a nova 404. - Componentes: PageHero e SectionHead novos; BoardCard, CodeExample, PinRestrictions, SeriesTabMenu e ConnectionsDiagram refeitos, com abas e diálogo acessíveis. - Remove emojis, cores avulsas por série, caixa alta com tracking, texto menor que 12px e os pares slate-*/dark:*. - Comparador: "mostrar só as diferenças" e leitura de ?chips=. - Corrige overflow em 320/390px e ajusta accent/copper do tema claro para fechar 7:1. - scripts/auditar-temas.mjs passa a travar paleta crua, dark:, texto pequeno, emoji e contraste dos tokens. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016W1xmizFcmXLrmabSvfSuc * ci: roda lint, auditorias de design e build em cada PR Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016W1xmizFcmXLrmabSvfSuc --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
360 lines
12 KiB
React
360 lines
12 KiB
React
import Header from "@/components/Header";
|
|
import Footer from "@/components/Footer";
|
|
import BookCover from "@/components/BookCover";
|
|
import CodeSample from "@/components/CodeSample";
|
|
import Link from "next/link";
|
|
import { jsonLd, paginaMeta, SITE } from "@/lib/seo";
|
|
import {
|
|
ArrowRight,
|
|
ArrowUpRight,
|
|
BookOpen,
|
|
Cpu,
|
|
Gauge,
|
|
Radio,
|
|
ShieldCheck,
|
|
Terminal,
|
|
Wifi,
|
|
} from "lucide-react";
|
|
|
|
export const metadata = paginaMeta({
|
|
titulo: "Microcontroladores ESP32, o livro",
|
|
descricao:
|
|
"Conheça o livro Microcontroladores ESP32: conectividade, eficiência e desempenho. 12 partes e 78 capítulos em português sobre arquitetura, energia, rádio, periféricos e firmware.",
|
|
caminho: "/livro",
|
|
keywords: [
|
|
"livro ESP32",
|
|
"Microcontroladores ESP32",
|
|
"livro de ESP32 em português",
|
|
"Lucas Rayan Guerra",
|
|
"Ciência Embarcada",
|
|
],
|
|
});
|
|
|
|
const CHAPTERS = [
|
|
{
|
|
title: "O ecossistema ESP32",
|
|
desc: "Como as famílias se organizam, o que muda entre Xtensa e RISC-V e por que a escolha do chip começa pelo problema.",
|
|
topics: ["Famílias e sufixos", "Critérios de escolha", "Ferramentas de apoio"],
|
|
icon: Cpu,
|
|
},
|
|
{
|
|
title: "Arquitetura e memória",
|
|
desc: "Núcleos, caches, SRAM, PSRAM e o caminho entre o código em flash e a execução em alta velocidade.",
|
|
topics: ["Mapa de memória", "PSRAM na prática", "Caches e latência"],
|
|
icon: Gauge,
|
|
},
|
|
{
|
|
title: "Energia e autonomia",
|
|
desc: "Os modos de sono, o custo real do rádio e as decisões de hardware que definem a vida útil da bateria.",
|
|
topics: ["Deep sleep", "Domínios de energia", "Orçamento de consumo"],
|
|
icon: Gauge,
|
|
},
|
|
{
|
|
title: "Conectividade",
|
|
desc: "Wi-Fi, BLE, Thread, Zigbee e Matter: o que cada rádio resolve e onde a arquitetura começa a pesar.",
|
|
topics: ["Wi-Fi 6 e TWT", "BLE e malhas", "Matter e 802.15.4"],
|
|
icon: Radio,
|
|
},
|
|
{
|
|
title: "Periféricos e pinagem",
|
|
desc: "GPIO, ADC, I2S, USB, MIPI e as restrições que só aparecem quando o hardware já está na placa.",
|
|
topics: ["Pinos de strapping", "ADC e rádio", "USB nativo"],
|
|
icon: Wifi,
|
|
},
|
|
{
|
|
title: "Do protótipo ao produto",
|
|
desc: "Firmware, partições, OTA, segurança e os cuidados de engenharia que sobrevivem ao primeiro deploy.",
|
|
topics: ["ESP-IDF e Arduino", "OTA e rollback", "Secure boot"],
|
|
icon: ShieldCheck,
|
|
},
|
|
];
|
|
|
|
const ESP_IDF = `#include "driver/gpio.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
|
|
#define LED GPIO_NUM_2
|
|
|
|
void app_main(void)
|
|
{
|
|
gpio_reset_pin(LED);
|
|
gpio_set_direction(LED, GPIO_MODE_OUTPUT);
|
|
|
|
while (1) {
|
|
gpio_set_level(LED, 1);
|
|
vTaskDelay(pdMS_TO_TICKS(500));
|
|
gpio_set_level(LED, 0);
|
|
vTaskDelay(pdMS_TO_TICKS(500));
|
|
}
|
|
}`;
|
|
|
|
const ARDUINO = `#include <WiFi.h>
|
|
|
|
const char *ssid = "SUA_REDE";
|
|
const char *senha = "SUA_SENHA";
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
WiFi.begin(ssid, senha);
|
|
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(500);
|
|
Serial.print(".");
|
|
}
|
|
|
|
Serial.println(WiFi.localIP());
|
|
}
|
|
|
|
void loop() {}`;
|
|
|
|
const DEEP_SLEEP = `#include "esp_sleep.h"
|
|
#include "esp_log.h"
|
|
|
|
void app_main(void)
|
|
{
|
|
uint64_t intervalo_us = 30ULL * 1000000ULL;
|
|
esp_sleep_enable_timer_wakeup(intervalo_us);
|
|
|
|
ESP_LOGI("energia", "dormindo por 30 segundos");
|
|
esp_deep_sleep_start();
|
|
}`;
|
|
|
|
const FACTS = [
|
|
["Idioma", "Português"],
|
|
["Partes", "12"],
|
|
["Capítulos", "78"],
|
|
["Digital", "Amazon Kindle"],
|
|
["Impresso", "UICLAP"],
|
|
["ISBN", SITE.livroIsbn],
|
|
];
|
|
|
|
export default function LivroPage() {
|
|
return (
|
|
<div className="site-canvas min-h-screen">
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.livro()) }}
|
|
/>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{
|
|
__html: JSON.stringify(
|
|
jsonLd.trilha([
|
|
{ nome: "Início", caminho: "/" },
|
|
{ nome: "Livro", caminho: "/livro" },
|
|
])
|
|
),
|
|
}}
|
|
/>
|
|
|
|
<Header />
|
|
|
|
<main id="conteudo">
|
|
<section className="shell pt-8 sm:pt-12">
|
|
<nav aria-label="Trilha de navegação" className="flex items-center gap-2 text-sm text-muted">
|
|
<Link href="/" className="transition-colors hover:text-accent">
|
|
Início
|
|
</Link>
|
|
<span aria-hidden="true" className="text-line-strong">/</span>
|
|
<span aria-current="page" className="text-ink">Livro</span>
|
|
</nav>
|
|
|
|
<div className="mt-7 grid items-center gap-10 lg:grid-cols-[0.84fr_1.16fr] lg:gap-16">
|
|
<div className="order-1 lg:order-2">
|
|
<span className="chip chip-accent">
|
|
<BookOpen className="h-3.5 w-3.5" aria-hidden="true" />
|
|
Livro novo · 1ª edição
|
|
</span>
|
|
<h1 className="page-title mt-5 text-[clamp(1.85rem,8vw,2.5rem)] sm:text-[clamp(2.5rem,5.4vw,4.4rem)]">
|
|
Microcontroladores ESP32
|
|
</h1>
|
|
<p className="mt-3 text-lg font-medium text-copper">{SITE.livroSubtitulo}</p>
|
|
<p className="lede mt-6 max-w-2xl">
|
|
Um percurso completo pelo ecossistema ESP32 — da arquitetura do chip à implantação
|
|
de produtos conectados. São 12 partes e 78 capítulos que cobrem Arduino e ESP-IDF,
|
|
FreeRTOS, Wi-Fi, BLE, Thread e Matter, periféricos, depuração, baixo consumo e segurança.
|
|
</p>
|
|
|
|
<div className="mt-8 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center">
|
|
<a
|
|
href={SITE.livroAmazon}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="btn btn-primary w-full sm:w-auto"
|
|
>
|
|
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
|
Comprar digital
|
|
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
|
</a>
|
|
<a
|
|
href={SITE.livroUiclap}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="btn btn-ghost w-full sm:w-auto"
|
|
>
|
|
Comprar impresso
|
|
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
|
</a>
|
|
<Link href="/series" className="inline-flex min-h-11 items-center justify-center gap-1.5 px-2 text-sm font-medium text-accent transition-colors hover:text-accent-strong">
|
|
Explorar a documentação
|
|
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
|
</Link>
|
|
</div>
|
|
|
|
<dl className="mt-9 grid grid-cols-2 gap-2.5 sm:grid-cols-3">
|
|
{FACTS.map(([label, value]) => (
|
|
<div key={label} className="rounded-2xl bg-surface-2 px-4 py-3">
|
|
<dt className="text-[0.6875rem] font-semibold text-muted">{label}</dt>
|
|
<dd className="mt-0.5 text-sm font-semibold text-ink">{value}</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
</div>
|
|
|
|
<div className="relative order-2 overflow-hidden rounded-[2rem] bg-[#0b0d10] p-8 ring-1 ring-white/10 sm:rounded-[2.5rem] sm:p-12 lg:order-1">
|
|
<div
|
|
className="pointer-events-none absolute left-1/2 top-1/2 -z-0 h-72 w-72 -translate-x-1/2 -translate-y-1/2 rounded-full bg-[#2dd4bf]/15 blur-3xl"
|
|
aria-hidden="true"
|
|
/>
|
|
<div className="relative mx-auto w-[min(16rem,76%)]">
|
|
<BookCover />
|
|
</div>
|
|
<div className="relative mt-9 flex items-end justify-between gap-4 border-t border-white/10 pt-4 text-xs text-[#a6afbd]">
|
|
<span>Lucas Rayan Guerra</span>
|
|
<span>Ciência Embarcada</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="shell section" aria-labelledby="sumario-titulo">
|
|
<div className="grid gap-8 lg:grid-cols-[0.72fr_1.28fr] lg:gap-16">
|
|
<div>
|
|
<p className="eyebrow">Sumário</p>
|
|
<h2 id="sumario-titulo" className="display mt-4 text-[clamp(2rem,4.6vw,3.4rem)]">
|
|
Uma linha de raciocínio, do chip ao produto.
|
|
</h2>
|
|
</div>
|
|
<div className="lg:pt-2">
|
|
<p className="lede">
|
|
A ordem acompanha o projeto real: entender o chip, medir energia, conectar, expor
|
|
periféricos e sustentar o produto. Os seis eixos abaixo mostram como as 12 partes
|
|
se organizam.
|
|
</p>
|
|
<p className="mt-4 text-sm text-muted">
|
|
78 capítulos, com exercícios e projetos ao longo do percurso.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-10 grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
{CHAPTERS.map((chapter) => {
|
|
const Icon = chapter.icon;
|
|
return (
|
|
<article key={chapter.title} className="card flex flex-col p-5 sm:p-6">
|
|
<span className="grid h-11 w-11 place-items-center rounded-2xl bg-accent-soft text-accent">
|
|
<Icon className="h-5 w-5" aria-hidden="true" />
|
|
</span>
|
|
<h3 className="mt-5 font-display text-xl font-semibold tracking-[-0.03em] text-ink">{chapter.title}</h3>
|
|
<p className="mt-2 flex-1 text-sm leading-relaxed text-muted">{chapter.desc}</p>
|
|
<ul className="mt-5 flex flex-wrap gap-1.5">
|
|
{chapter.topics.map((topic) => (
|
|
<li key={topic} className="chip">
|
|
{topic}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</article>
|
|
);
|
|
})}
|
|
</div>
|
|
</section>
|
|
|
|
<section className="border-y border-line bg-surface/70" aria-labelledby="codigo-titulo">
|
|
<div className="shell section">
|
|
<div className="grid gap-10 lg:grid-cols-[0.7fr_1.3fr] lg:gap-16">
|
|
<div className="min-w-0 lg:sticky lg:top-28 lg:self-start">
|
|
<p className="eyebrow">Código</p>
|
|
<h2 id="codigo-titulo" className="display mt-4 text-[clamp(2rem,4.6vw,3.4rem)]">
|
|
Exemplos curtos, prontos para a bancada.
|
|
</h2>
|
|
<p className="lede mt-4">
|
|
Os trechos abaixo são originais e servem como ponto de partida. Ajuste o pino, a rede
|
|
e a frequência ao seu hardware antes de gravar.
|
|
</p>
|
|
<div className="mt-6 rounded-2xl border border-line bg-surface p-4">
|
|
<p className="flex items-center gap-2 text-sm font-semibold text-ink">
|
|
<Terminal className="h-4 w-4 text-accent" aria-hidden="true" />
|
|
Sem conteúdo protegido
|
|
</p>
|
|
<p className="mt-2 text-xs leading-relaxed text-muted">
|
|
Esta página apresenta apenas a ficha do livro e exemplos autorais. O texto integral,
|
|
PDF, EPUB e arquivos intermediários não são distribuídos pelo ESPDocs.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="min-w-0 space-y-7">
|
|
<CodeSample
|
|
label="Ponto de partida · ESP-IDF"
|
|
language="C"
|
|
code={ESP_IDF}
|
|
note="Pisca o GPIO 2 usando a API atual do ESP-IDF e uma task do FreeRTOS."
|
|
/>
|
|
<CodeSample
|
|
label="Conectividade · Arduino"
|
|
language="C++"
|
|
code={ARDUINO}
|
|
note="Conexão Wi-Fi mínima, com espera ativa e impressão do IP obtido."
|
|
/>
|
|
<CodeSample
|
|
label="Energia · deep sleep"
|
|
language="C · ESP-IDF"
|
|
code={DEEP_SLEEP}
|
|
note="Timer de 30 segundos e entrada no modo de menor consumo disponível."
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="shell section pb-20 md:pb-28">
|
|
<div className="mx-auto max-w-3xl text-center">
|
|
<p className="eyebrow">Para quem é</p>
|
|
<h2 className="display mt-4 text-[clamp(2rem,4.5vw,3.2rem)]">
|
|
Para quem já cansou de juntar pedaços de datasheet.
|
|
</h2>
|
|
<p className="lede mx-auto mt-4 max-w-2xl">
|
|
Estudantes, makers e engenheiros de firmware que querem uma visão coerente do
|
|
ecossistema — sem abandonar a fonte oficial.
|
|
</p>
|
|
<div className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
|
|
<a
|
|
href={SITE.livroAmazon}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="btn btn-primary w-full sm:w-auto"
|
|
>
|
|
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
|
Comprar digital
|
|
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
|
</a>
|
|
<a
|
|
href={SITE.livroUiclap}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="btn btn-ghost w-full sm:w-auto"
|
|
>
|
|
Comprar impresso
|
|
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<Footer />
|
|
</div>
|
|
);
|
|
}
|